From sebastian at fds-team.de Sat Oct 1 07:55:05 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Sat, 1 Oct 2016 14:55:05 +0200 Subject: user32: Also release GMEM_FIXED data in free_cached_data. (v2) Message-ID: <960698be-048b-5af6-eb4e-42b7cc64460a@fds-team.de> Signed-off-by: Sebastian Lackner --- Changes in v2: * Keep the tests (but we have to mark them as broken on < Vista). dlls/user32/clipboard.c | 6 +----- dlls/user32/tests/clipboard.c | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/dlls/user32/clipboard.c b/dlls/user32/clipboard.c index 0d48984..d33459c 100644 --- a/dlls/user32/clipboard.c +++ b/dlls/user32/clipboard.c @@ -326,11 +326,7 @@ static void free_cached_data( struct cached_format *cache ) GlobalFree( cache->handle ); break; default: - if ((ptr = GlobalLock( cache->handle )) && ptr != cache->handle) - { - GlobalUnlock( cache->handle ); - GlobalFree( cache->handle ); - } + GlobalFree( cache->handle ); break; } list_remove( &cache->entry ); diff --git a/dlls/user32/tests/clipboard.c b/dlls/user32/tests/clipboard.c index 832eca6..69bdba8 100644 --- a/dlls/user32/tests/clipboard.c +++ b/dlls/user32/tests/clipboard.c @@ -1590,9 +1590,7 @@ static BOOL is_fixed( HANDLE handle ) static BOOL is_freed( HANDLE handle ) { - void *ptr = GlobalLock( handle ); - if (ptr) GlobalUnlock( handle ); - return !ptr; + return !GlobalSize( handle ); } static UINT format_id; @@ -1602,7 +1600,8 @@ static const LOGPALETTE logpalette = { 0x300, 1, {{ 0x12, 0x34, 0x56, 0x78 }}}; static void test_handles( HWND hwnd ) { - HGLOBAL h, htext, htext2, htext3, htext4, htext5, hfixed, hmoveable, empty_fixed, empty_moveable; + HGLOBAL h, htext, htext2, htext3, htext4, htext5; + HGLOBAL hfixed, hfixed2, hmoveable, empty_fixed, empty_moveable; void *ptr; UINT format_id2 = RegisterClipboardFormatA( "another format" ); BOOL r; @@ -1622,6 +1621,7 @@ static void test_handles( HWND hwnd ) palette = CreatePalette( &logpalette ); hfixed = GlobalAlloc( GMEM_FIXED, 17 ); + hfixed2 = GlobalAlloc( GMEM_FIXED, 17 ); ok( is_fixed( hfixed ), "expected fixed mem %p\n", hfixed ); ok( GlobalSize( hfixed ) == 17, "wrong size %lu\n", GlobalSize( hfixed )); @@ -1682,8 +1682,8 @@ static void test_handles( HWND hwnd ) h = SetClipboardData( format_id2, empty_fixed ); ok( h == empty_fixed, "got %p\n", h ); ok( is_fixed( h ), "expected fixed mem %p\n", h ); - h = SetClipboardData( 0xdeadbeef, hfixed ); - ok( h == hfixed, "got %p\n", h ); + h = SetClipboardData( 0xdeadbeef, hfixed2 ); + ok( h == hfixed2, "got %p\n", h ); ok( is_fixed( h ), "expected fixed mem %p\n", h ); h = SetClipboardData( 0xdeadbabe, hmoveable ); ok( h == hmoveable, "got %p\n", h ); @@ -1719,7 +1719,7 @@ static void test_handles( HWND hwnd ) ok( is_fixed( data ), "expected fixed mem %p\n", data ); data = GetClipboardData( 0xdeadbeef ); - ok( data == hfixed, "wrong data %p\n", data ); + ok( data == hfixed2, "wrong data %p\n", data ); ok( is_fixed( data ), "expected fixed mem %p\n", data ); data = GetClipboardData( 0xdeadbabe ); @@ -1734,6 +1734,11 @@ static void test_handles( HWND hwnd ) ok( is_moveable( h ), "expected moveable mem %p\n", h ); ok( is_freed( htext5 ), "expected freed mem %p\n", htext5 ); + h = SetClipboardData( 0xdeadbeef, hfixed ); + ok( h == hfixed, "got %p\n", h ); + ok( is_fixed( h ), "expected fixed mem %p\n", h ); + ok( is_freed( hfixed2 ) || broken( !is_freed( hfixed2 )) /* < Vista */, "expected freed mem %p\n", hfixed2 ); + r = CloseClipboard(); ok( r, "gle %d\n", GetLastError() ); -- 2.9.0 From nsivov at codeweavers.com Sat Oct 1 08:31:31 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Sat, 1 Oct 2016 16:31:31 +0300 Subject: [PATCH] d2d1: Initial implementation of HWND render target Message-ID: <20161001133131.13746-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/d2d1/Makefile.in | 3 +- dlls/d2d1/d2d1_private.h | 19 +- dlls/d2d1/dc_render_target.c | 2 +- dlls/d2d1/factory.c | 25 +- dlls/d2d1/hwnd_render_target.c | 869 +++++++++++++++++++++++++++++++++++++++++ dlls/d2d1/render_target.c | 16 +- dlls/d2d1/tests/d2d1.c | 49 +++ 7 files changed, 977 insertions(+), 6 deletions(-) create mode 100644 dlls/d2d1/hwnd_render_target.c diff --git a/dlls/d2d1/Makefile.in b/dlls/d2d1/Makefile.in index 06f7bde..deacd7a 100644 --- a/dlls/d2d1/Makefile.in +++ b/dlls/d2d1/Makefile.in @@ -1,6 +1,6 @@ MODULE = d2d1.dll IMPORTLIB = d2d1 -IMPORTS = d3d10_1 dxguid uuid gdi32 +IMPORTS = d3d10_1 dxguid uuid gdi32 user32 DELAYIMPORTS = dwrite C_SRCS = \ @@ -9,6 +9,7 @@ C_SRCS = \ dc_render_target.c \ factory.c \ geometry.c \ + hwnd_render_target.c \ mesh.c \ render_target.c \ state_block.c \ diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index fa7e464..e893826 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -96,7 +96,9 @@ struct d2d_d3d_render_target HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory, IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN; -HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN; +HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN; +void d2d_d3d_render_target_set_pixel_size(ID2D1RenderTarget *render_target, UINT32 width, UINT32 height) + DECLSPEC_HIDDEN; struct d2d_wic_render_target { @@ -131,6 +133,21 @@ struct d2d_dc_render_target HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID2D1Factory *factory, ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN; +struct d2d_hwnd_render_target +{ + ID2D1HwndRenderTarget ID2D1HwndRenderTarget_iface; + LONG refcount; + + ID2D1RenderTarget *dxgi_target; + IDXGISwapChain *swapchain; + UINT sync_interval; + HWND hwnd; +}; + +HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target, ID2D1Factory *factory, + ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc, + const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_desc) DECLSPEC_HIDDEN; + struct d2d_gradient { ID2D1GradientStopCollection ID2D1GradientStopCollection_iface; diff --git a/dlls/d2d1/dc_render_target.c b/dlls/d2d1/dc_render_target.c index ae87a0d..1cf2c8d 100644 --- a/dlls/d2d1/dc_render_target.c +++ b/dlls/d2d1/dc_render_target.c @@ -731,7 +731,7 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget } /* Switch dxgi target to new surface. */ - if (FAILED(hr = d2d_d3d_render_target_update_surface(render_target->dxgi_target, dxgi_surface))) + if (FAILED(hr = d2d_d3d_render_target_create_rtv(render_target->dxgi_target, dxgi_surface))) { WARN("Failed to set new surface, hr %#x.\n", hr); IDXGISurface1_Release(dxgi_surface); diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 66ed25b..a31af98 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -271,9 +271,30 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory const D2D1_RENDER_TARGET_PROPERTIES *desc, const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_rt_desc, ID2D1HwndRenderTarget **render_target) { - FIXME("iface %p, desc %p, hwnd_rt_desc %p, render_target %p stub!\n", iface, desc, hwnd_rt_desc, render_target); + struct d2d_factory *factory = impl_from_ID2D1Factory(iface); + struct d2d_hwnd_render_target *object; + ID3D10Device1 *device; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, desc %p, hwnd_rt_desc %p, render_target %p\n", iface, desc, hwnd_rt_desc, render_target); + + if (FAILED(hr = d2d_factory_get_device(factory, &device))) + return hr; + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d2d_hwnd_render_target_init(object, iface, device, desc, hwnd_rt_desc))) + { + WARN("Failed to initialize render target, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + TRACE("Created render target %p.\n", object); + *render_target = &object->ID2D1HwndRenderTarget_iface; + + return S_OK; } static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDxgiSurfaceRenderTarget(ID2D1Factory *iface, diff --git a/dlls/d2d1/hwnd_render_target.c b/dlls/d2d1/hwnd_render_target.c new file mode 100644 index 0000000..e9092b6 --- /dev/null +++ b/dlls/d2d1/hwnd_render_target.c @@ -0,0 +1,869 @@ +/* + * Copyright 2014 Henri Verbeet for CodeWeavers + * Copyright 2016 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include "d2d1_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d2d); + +static void render_target_present(struct d2d_hwnd_render_target *render_target) +{ + HRESULT hr; + + if (FAILED(hr = IDXGISwapChain_Present(render_target->swapchain, render_target->sync_interval, 0))) + WARN("Present failed, %#x.\n", hr); +} + +static inline struct d2d_hwnd_render_target *impl_from_ID2D1HwndRenderTarget(ID2D1HwndRenderTarget *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_hwnd_render_target, ID2D1HwndRenderTarget_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_QueryInterface(ID2D1HwndRenderTarget *iface, + REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1HwndRenderTarget) + || IsEqualGUID(iid, &IID_ID2D1RenderTarget) + || IsEqualGUID(iid, &IID_ID2D1Resource) + || IsEqualGUID(iid, &IID_IUnknown)) + { + ID2D1HwndRenderTarget_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_hwnd_render_target_AddRef(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + ULONG refcount = InterlockedIncrement(&render_target->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_hwnd_render_target_Release(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + ULONG refcount = InterlockedDecrement(&render_target->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (!refcount) + { + ID2D1RenderTarget_Release(render_target->dxgi_target); + IDXGISwapChain_Release(render_target->swapchain); + HeapFree(GetProcessHeap(), 0, render_target); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetFactory(ID2D1HwndRenderTarget *iface, ID2D1Factory **factory) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, factory %p.\n", iface, factory); + + ID2D1RenderTarget_GetFactory(render_target->dxgi_target, factory); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateBitmap(ID2D1HwndRenderTarget *iface, + D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, size {%u, %u}, src_data %p, pitch %u, desc %p, bitmap %p.\n", + iface, size.width, size.height, src_data, pitch, desc, bitmap); + + return ID2D1RenderTarget_CreateBitmap(render_target->dxgi_target, size, src_data, pitch, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateBitmapFromWicBitmap(ID2D1HwndRenderTarget *iface, + IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, bitmap_source %p, desc %p, bitmap %p.\n", + iface, bitmap_source, desc, bitmap); + + return ID2D1RenderTarget_CreateBitmapFromWicBitmap(render_target->dxgi_target, bitmap_source, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateSharedBitmap(ID2D1HwndRenderTarget *iface, + REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, iid %s, data %p, desc %p, bitmap %p.\n", + iface, debugstr_guid(iid), data, desc, bitmap); + + return ID2D1RenderTarget_CreateSharedBitmap(render_target->dxgi_target, iid, data, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateBitmapBrush(ID2D1HwndRenderTarget *iface, + ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc, + const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1BitmapBrush **brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p.\n", + iface, bitmap, bitmap_brush_desc, brush_desc, brush); + + return ID2D1RenderTarget_CreateBitmapBrush(render_target->dxgi_target, + bitmap, bitmap_brush_desc, brush_desc, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateSolidColorBrush(ID2D1HwndRenderTarget *iface, + const D2D1_COLOR_F *color, const D2D1_BRUSH_PROPERTIES *desc, ID2D1SolidColorBrush **brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, color %p, desc %p, brush %p.\n", iface, color, desc, brush); + + return ID2D1RenderTarget_CreateSolidColorBrush(render_target->dxgi_target, color, desc, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateGradientStopCollection(ID2D1HwndRenderTarget *iface, + const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode, + ID2D1GradientStopCollection **gradient) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n", + iface, stops, stop_count, gamma, extend_mode, gradient); + + return ID2D1RenderTarget_CreateGradientStopCollection(render_target->dxgi_target, + stops, stop_count, gamma, extend_mode, gradient); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateLinearGradientBrush(ID2D1HwndRenderTarget *iface, + const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1GradientStopCollection *gradient, ID2D1LinearGradientBrush **brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n", + iface, gradient_brush_desc, brush_desc, gradient, brush); + + return ID2D1RenderTarget_CreateLinearGradientBrush(render_target->dxgi_target, + gradient_brush_desc, brush_desc, gradient, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateRadialGradientBrush(ID2D1HwndRenderTarget *iface, + const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1GradientStopCollection *gradient, ID2D1RadialGradientBrush **brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n", + iface, gradient_brush_desc, brush_desc, gradient, brush); + + return ID2D1RenderTarget_CreateRadialGradientBrush(render_target->dxgi_target, + gradient_brush_desc, brush_desc, gradient, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateCompatibleRenderTarget(ID2D1HwndRenderTarget *iface, + const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **render_target) +{ + struct d2d_hwnd_render_target *rt = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p,\n", + iface, size, pixel_size, format, options, render_target); + + return ID2D1RenderTarget_CreateCompatibleRenderTarget(rt->dxgi_target, + size, pixel_size, format, options, render_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateLayer(ID2D1HwndRenderTarget *iface, + const D2D1_SIZE_F *size, ID2D1Layer **layer) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, size %p, layer %p.\n", iface, size, layer); + + return ID2D1RenderTarget_CreateLayer(render_target->dxgi_target, size, layer); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateMesh(ID2D1HwndRenderTarget *iface, ID2D1Mesh **mesh) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, mesh %p.\n", iface, mesh); + + return ID2D1RenderTarget_CreateMesh(render_target->dxgi_target, mesh); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawLine(ID2D1HwndRenderTarget *iface, + D2D1_POINT_2F p0, D2D1_POINT_2F p1, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, p0 {%.8e, %.8e}, p1 {%.8e, %.8e}, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, p0.x, p0.y, p1.x, p1.y, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawLine(render_target->dxgi_target, p0, p1, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawRectangle(ID2D1HwndRenderTarget *iface, + const D2D1_RECT_F *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, rect, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawRectangle(render_target->dxgi_target, rect, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillRectangle(ID2D1HwndRenderTarget *iface, + const D2D1_RECT_F *rect, ID2D1Brush *brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p.\n", iface, rect, brush); + + ID2D1RenderTarget_FillRectangle(render_target->dxgi_target, rect, brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawRoundedRectangle(ID2D1HwndRenderTarget *iface, + const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, rect, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawRoundedRectangle(render_target->dxgi_target, rect, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillRoundedRectangle(ID2D1HwndRenderTarget *iface, + const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p.\n", iface, rect, brush); + + ID2D1RenderTarget_FillRoundedRectangle(render_target->dxgi_target, rect, brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawEllipse(ID2D1HwndRenderTarget *iface, + const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, ellipse %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, ellipse, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawEllipse(render_target->dxgi_target, ellipse, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillEllipse(ID2D1HwndRenderTarget *iface, + const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, ellipse %p, brush %p.\n", iface, ellipse, brush); + + ID2D1RenderTarget_FillEllipse(render_target->dxgi_target, ellipse, brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawGeometry(ID2D1HwndRenderTarget *iface, + ID2D1Geometry *geometry, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, geometry %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, geometry, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawGeometry(render_target->dxgi_target, geometry, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillGeometry(ID2D1HwndRenderTarget *iface, + ID2D1Geometry *geometry, ID2D1Brush *brush, ID2D1Brush *opacity_brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, geometry %p, brush %p, opacity_brush %p.\n", iface, geometry, brush, opacity_brush); + + ID2D1RenderTarget_FillGeometry(render_target->dxgi_target, geometry, brush, opacity_brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillMesh(ID2D1HwndRenderTarget *iface, + ID2D1Mesh *mesh, ID2D1Brush *brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, mesh %p, brush %p.\n", iface, mesh, brush); + + ID2D1RenderTarget_FillMesh(render_target->dxgi_target, mesh, brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillOpacityMask(ID2D1HwndRenderTarget *iface, + ID2D1Bitmap *mask, ID2D1Brush *brush, D2D1_OPACITY_MASK_CONTENT content, + const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, mask %p, brush %p, content %#x, dst_rect %p, src_rect %p.\n", + iface, mask, brush, content, dst_rect, src_rect); + + ID2D1RenderTarget_FillOpacityMask(render_target->dxgi_target, + mask, brush, content, dst_rect, src_rect); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawBitmap(ID2D1HwndRenderTarget *iface, + ID2D1Bitmap *bitmap, const D2D1_RECT_F *dst_rect, float opacity, + D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, const D2D1_RECT_F *src_rect) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, bitmap %p, dst_rect %p, opacity %.8e, interpolation_mode %#x, src_rect %p.\n", + iface, bitmap, dst_rect, opacity, interpolation_mode, src_rect); + + ID2D1RenderTarget_DrawBitmap(render_target->dxgi_target, + bitmap, dst_rect, opacity, interpolation_mode, src_rect); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawText(ID2D1HwndRenderTarget *iface, + const WCHAR *string, UINT32 string_len, IDWriteTextFormat *text_format, const D2D1_RECT_F *layout_rect, + ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuring_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, string %s, string_len %u, text_format %p, layout_rect %p, " + "brush %p, options %#x, measuring_mode %#x.\n", + iface, debugstr_wn(string, string_len), string_len, text_format, layout_rect, + brush, options, measuring_mode); + + ID2D1RenderTarget_DrawText(render_target->dxgi_target, string, string_len, + text_format, layout_rect, brush, options, measuring_mode); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawTextLayout(ID2D1HwndRenderTarget *iface, + D2D1_POINT_2F origin, IDWriteTextLayout *layout, ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, origin {%.8e, %.8e}, layout %p, brush %p, options %#x.\n", + iface, origin.x, origin.y, layout, brush, options); + + ID2D1RenderTarget_DrawTextLayout(render_target->dxgi_target, origin, layout, brush, options); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawGlyphRun(ID2D1HwndRenderTarget *iface, + D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush, + DWRITE_MEASURING_MODE measuring_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, baseline_origin {%.8e, %.8e}, glyph_run %p, brush %p, measuring_mode %#x.\n", + iface, baseline_origin.x, baseline_origin.y, glyph_run, brush, measuring_mode); + + ID2D1RenderTarget_DrawGlyphRun(render_target->dxgi_target, + baseline_origin, glyph_run, brush, measuring_mode); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetTransform(ID2D1HwndRenderTarget *iface, + const D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, transform %p.\n", iface, transform); + + ID2D1RenderTarget_SetTransform(render_target->dxgi_target, transform); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetTransform(ID2D1HwndRenderTarget *iface, + D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, transform %p.\n", iface, transform); + + ID2D1RenderTarget_GetTransform(render_target->dxgi_target, transform); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetAntialiasMode(ID2D1HwndRenderTarget *iface, + D2D1_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, antialias_mode %#x.\n", iface, antialias_mode); + + ID2D1RenderTarget_SetAntialiasMode(render_target->dxgi_target, antialias_mode); +} + +static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_hwnd_render_target_GetAntialiasMode(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetAntialiasMode(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetTextAntialiasMode(ID2D1HwndRenderTarget *iface, + D2D1_TEXT_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, antialias_mode %#x.\n", iface, antialias_mode); + + ID2D1RenderTarget_SetTextAntialiasMode(render_target->dxgi_target, antialias_mode); +} + +static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_hwnd_render_target_GetTextAntialiasMode( + ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetTextAntialiasMode(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetTextRenderingParams(ID2D1HwndRenderTarget *iface, + IDWriteRenderingParams *text_rendering_params) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params); + + ID2D1RenderTarget_SetTextRenderingParams(render_target->dxgi_target, text_rendering_params); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetTextRenderingParams(ID2D1HwndRenderTarget *iface, + IDWriteRenderingParams **text_rendering_params) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params); + + ID2D1RenderTarget_GetTextRenderingParams(render_target->dxgi_target, text_rendering_params); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetTags(ID2D1HwndRenderTarget *iface, D2D1_TAG tag1, D2D1_TAG tag2) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, tag1 %s, tag2 %s.\n", iface, wine_dbgstr_longlong(tag1), wine_dbgstr_longlong(tag2)); + + ID2D1RenderTarget_SetTags(render_target->dxgi_target, tag1, tag2); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetTags(ID2D1HwndRenderTarget *iface, D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + ID2D1RenderTarget_GetTags(render_target->dxgi_target, tag1, tag2); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_PushLayer(ID2D1HwndRenderTarget *iface, + const D2D1_LAYER_PARAMETERS *layer_parameters, ID2D1Layer *layer) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, layer_parameters %p, layer %p.\n", iface, layer_parameters, layer); + + ID2D1RenderTarget_PushLayer(render_target->dxgi_target, layer_parameters, layer); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_PopLayer(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_PopLayer(render_target->dxgi_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_Flush(ID2D1HwndRenderTarget *iface, D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + HRESULT hr; + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + hr = ID2D1RenderTarget_Flush(render_target->dxgi_target, tag1, tag2); + render_target_present(render_target); + + return hr; +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SaveDrawingState(ID2D1HwndRenderTarget *iface, + ID2D1DrawingStateBlock *state_block) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, state_block %p.\n", iface, state_block); + + ID2D1RenderTarget_SaveDrawingState(render_target->dxgi_target, state_block); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_RestoreDrawingState(ID2D1HwndRenderTarget *iface, + ID2D1DrawingStateBlock *state_block) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, state_block %p.\n", iface, state_block); + + ID2D1RenderTarget_RestoreDrawingState(render_target->dxgi_target, state_block); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_PushAxisAlignedClip(ID2D1HwndRenderTarget *iface, + const D2D1_RECT_F *clip_rect, D2D1_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, clip_rect %p, antialias_mode %#x.\n", iface, clip_rect, antialias_mode); + + ID2D1RenderTarget_PushAxisAlignedClip(render_target->dxgi_target, clip_rect, antialias_mode); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_PopAxisAlignedClip(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_PopAxisAlignedClip(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_Clear(ID2D1HwndRenderTarget *iface, const D2D1_COLOR_F *color) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, color %p.\n", iface, color); + + ID2D1RenderTarget_Clear(render_target->dxgi_target, color); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_BeginDraw(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_BeginDraw(render_target->dxgi_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_EndDraw(ID2D1HwndRenderTarget *iface, + D2D1_TAG *tag1, D2D1_TAG *tag2) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + HRESULT hr; + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + hr = ID2D1RenderTarget_EndDraw(render_target->dxgi_target, tag1, tag2); + render_target_present(render_target); + + return hr; +} + +static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_hwnd_render_target_GetPixelFormat(ID2D1HwndRenderTarget *iface, + D2D1_PIXEL_FORMAT *format) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, format %p.\n", iface, format); + + *format = ID2D1RenderTarget_GetPixelFormat(render_target->dxgi_target); + return format; +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetDpi(ID2D1HwndRenderTarget *iface, float dpi_x, float dpi_y) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, dpi_x %.8e, dpi_y %.8e.\n", iface, dpi_x, dpi_y); + + ID2D1RenderTarget_SetDpi(render_target->dxgi_target, dpi_x, dpi_y); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetDpi(ID2D1HwndRenderTarget *iface, float *dpi_x, float *dpi_y) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y); + + ID2D1RenderTarget_GetDpi(render_target->dxgi_target, dpi_x, dpi_y); +} + +static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_hwnd_render_target_GetSize(ID2D1HwndRenderTarget *iface, D2D1_SIZE_F *size) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, size %p.\n", iface, size); + + *size = ID2D1RenderTarget_GetSize(render_target->dxgi_target); + return size; +} + +static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_hwnd_render_target_GetPixelSize(ID2D1HwndRenderTarget *iface, + D2D1_SIZE_U *pixel_size) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, pixel_size %p.\n", iface, pixel_size); + + *pixel_size = ID2D1RenderTarget_GetPixelSize(render_target->dxgi_target); + return pixel_size; +} + +static UINT32 STDMETHODCALLTYPE d2d_hwnd_render_target_GetMaximumBitmapSize(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetMaximumBitmapSize(render_target->dxgi_target); +} + +static BOOL STDMETHODCALLTYPE d2d_hwnd_render_target_IsSupported(ID2D1HwndRenderTarget *iface, + const D2D1_RENDER_TARGET_PROPERTIES *desc) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + return ID2D1RenderTarget_IsSupported(render_target->dxgi_target, desc); +} + +static D2D1_WINDOW_STATE STDMETHODCALLTYPE d2d_hwnd_render_target_CheckWindowState(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return IDXGISwapChain_Present(render_target->swapchain, render_target->sync_interval, DXGI_PRESENT_TEST) == + DXGI_STATUS_OCCLUDED ? D2D1_WINDOW_STATE_OCCLUDED : D2D1_WINDOW_STATE_NONE; +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_Resize(ID2D1HwndRenderTarget *iface, const D2D1_SIZE_U size) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + IDXGISurface1 *dxgi_surface; + HRESULT hr; + + TRACE("iface %p, width %u, height %u.\n", iface, size.width, size.height); + + d2d_d3d_render_target_create_rtv(render_target->dxgi_target, NULL); + + if (SUCCEEDED(hr = IDXGISwapChain_ResizeBuffers(render_target->swapchain, 1, size.width, size.height, + DXGI_FORMAT_UNKNOWN, 0))) + { + if (FAILED(hr = IDXGISwapChain_GetBuffer(render_target->swapchain, 0, &IID_IDXGISurface1, + (void **)&dxgi_surface))) + { + WARN("Failed to get buffer, hr %#x.\n", hr); + return hr; + } + + hr = d2d_d3d_render_target_create_rtv(render_target->dxgi_target, dxgi_surface); + IDXGISurface1_Release(dxgi_surface); + } + + return hr; +} + +static HWND STDMETHODCALLTYPE d2d_hwnd_render_target_GetHwnd(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return render_target->hwnd; +} + +static const struct ID2D1HwndRenderTargetVtbl d2d_hwnd_render_target_vtbl = +{ + d2d_hwnd_render_target_QueryInterface, + d2d_hwnd_render_target_AddRef, + d2d_hwnd_render_target_Release, + d2d_hwnd_render_target_GetFactory, + d2d_hwnd_render_target_CreateBitmap, + d2d_hwnd_render_target_CreateBitmapFromWicBitmap, + d2d_hwnd_render_target_CreateSharedBitmap, + d2d_hwnd_render_target_CreateBitmapBrush, + d2d_hwnd_render_target_CreateSolidColorBrush, + d2d_hwnd_render_target_CreateGradientStopCollection, + d2d_hwnd_render_target_CreateLinearGradientBrush, + d2d_hwnd_render_target_CreateRadialGradientBrush, + d2d_hwnd_render_target_CreateCompatibleRenderTarget, + d2d_hwnd_render_target_CreateLayer, + d2d_hwnd_render_target_CreateMesh, + d2d_hwnd_render_target_DrawLine, + d2d_hwnd_render_target_DrawRectangle, + d2d_hwnd_render_target_FillRectangle, + d2d_hwnd_render_target_DrawRoundedRectangle, + d2d_hwnd_render_target_FillRoundedRectangle, + d2d_hwnd_render_target_DrawEllipse, + d2d_hwnd_render_target_FillEllipse, + d2d_hwnd_render_target_DrawGeometry, + d2d_hwnd_render_target_FillGeometry, + d2d_hwnd_render_target_FillMesh, + d2d_hwnd_render_target_FillOpacityMask, + d2d_hwnd_render_target_DrawBitmap, + d2d_hwnd_render_target_DrawText, + d2d_hwnd_render_target_DrawTextLayout, + d2d_hwnd_render_target_DrawGlyphRun, + d2d_hwnd_render_target_SetTransform, + d2d_hwnd_render_target_GetTransform, + d2d_hwnd_render_target_SetAntialiasMode, + d2d_hwnd_render_target_GetAntialiasMode, + d2d_hwnd_render_target_SetTextAntialiasMode, + d2d_hwnd_render_target_GetTextAntialiasMode, + d2d_hwnd_render_target_SetTextRenderingParams, + d2d_hwnd_render_target_GetTextRenderingParams, + d2d_hwnd_render_target_SetTags, + d2d_hwnd_render_target_GetTags, + d2d_hwnd_render_target_PushLayer, + d2d_hwnd_render_target_PopLayer, + d2d_hwnd_render_target_Flush, + d2d_hwnd_render_target_SaveDrawingState, + d2d_hwnd_render_target_RestoreDrawingState, + d2d_hwnd_render_target_PushAxisAlignedClip, + d2d_hwnd_render_target_PopAxisAlignedClip, + d2d_hwnd_render_target_Clear, + d2d_hwnd_render_target_BeginDraw, + d2d_hwnd_render_target_EndDraw, + d2d_hwnd_render_target_GetPixelFormat, + d2d_hwnd_render_target_SetDpi, + d2d_hwnd_render_target_GetDpi, + d2d_hwnd_render_target_GetSize, + d2d_hwnd_render_target_GetPixelSize, + d2d_hwnd_render_target_GetMaximumBitmapSize, + d2d_hwnd_render_target_IsSupported, + d2d_hwnd_render_target_CheckWindowState, + d2d_hwnd_render_target_Resize, + d2d_hwnd_render_target_GetHwnd +}; + +HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target, ID2D1Factory *factory, + ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc, + const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_rt_desc) +{ + D2D1_RENDER_TARGET_PROPERTIES dxgi_rt_desc; + DXGI_SWAP_CHAIN_DESC swapchain_desc; + IDXGIAdapter *dxgi_adapter; + IDXGIFactory *dxgi_factory; + IDXGISurface *dxgi_surface; + IDXGIDevice *dxgi_device; + HRESULT hr; + + if (!IsWindow(hwnd_rt_desc->hwnd)) + return HRESULT_FROM_WIN32(ERROR_INVALID_WINDOW_HANDLE); + + render_target->ID2D1HwndRenderTarget_iface.lpVtbl = &d2d_hwnd_render_target_vtbl; + render_target->refcount = 1; + render_target->hwnd = hwnd_rt_desc->hwnd; + render_target->sync_interval = hwnd_rt_desc->presentOptions & D2D1_PRESENT_OPTIONS_IMMEDIATELY ? 0 : 1; + + if (FAILED(hr = ID3D10Device1_QueryInterface(device, &IID_IDXGIDevice, (void **)&dxgi_device))) + { + WARN("Failed to get IDXGIDevice interface, hr %#x.\n", hr); + return hr; + } + + hr = IDXGIDevice_GetAdapter(dxgi_device, &dxgi_adapter); + IDXGIDevice_Release(dxgi_device); + if (FAILED(hr)) + { + WARN("Failed to get IDXGIAdapter interface, hr %#x.\n", hr); + return hr; + } + + hr = IDXGIAdapter_GetParent(dxgi_adapter, &IID_IDXGIFactory, (void **)&dxgi_factory); + IDXGIAdapter_Release(dxgi_adapter); + if (FAILED(hr)) + { + WARN("Failed to get IDXGIFactory interface, hr %#x.\n", hr); + return hr; + } + + dxgi_rt_desc = *desc; + if (dxgi_rt_desc.dpiX == 0.0f && dxgi_rt_desc.dpiY == 0.0f) + ID2D1Factory_GetDesktopDpi(factory, &dxgi_rt_desc.dpiX, &dxgi_rt_desc.dpiY); + + if (dxgi_rt_desc.pixelFormat.format == DXGI_FORMAT_UNKNOWN) + { + dxgi_rt_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + dxgi_rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE; + } + + swapchain_desc.BufferDesc.Width = hwnd_rt_desc->pixelSize.width; + swapchain_desc.BufferDesc.Height = hwnd_rt_desc->pixelSize.height; + swapchain_desc.BufferDesc.RefreshRate.Numerator = 60; + swapchain_desc.BufferDesc.RefreshRate.Denominator = 1; + swapchain_desc.BufferDesc.Format = dxgi_rt_desc.pixelFormat.format; + swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + swapchain_desc.SampleDesc.Count = 1; + swapchain_desc.SampleDesc.Quality = 0; + swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapchain_desc.BufferCount = 1; + swapchain_desc.OutputWindow = hwnd_rt_desc->hwnd; + swapchain_desc.Windowed = TRUE; + swapchain_desc.SwapEffect = hwnd_rt_desc->presentOptions & D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS ? + DXGI_SWAP_EFFECT_SEQUENTIAL : DXGI_SWAP_EFFECT_DISCARD; + swapchain_desc.Flags = 0; + + hr = IDXGIFactory_CreateSwapChain(dxgi_factory, (IUnknown *)device, &swapchain_desc, &render_target->swapchain); + IDXGIFactory_Release(dxgi_factory); + if (FAILED(hr)) + { + WARN("Failed to create a swapchain, hr %#x.\n", hr); + return hr; + } + + if (FAILED(hr = IDXGISwapChain_GetBuffer(render_target->swapchain, 0, &IID_IDXGISurface, (void **)&dxgi_surface))) + { + WARN("Failed to get buffer, hr %#x.\n", hr); + IDXGISwapChain_Release(render_target->swapchain); + return hr; + } + + hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, dxgi_surface, &dxgi_rt_desc, &render_target->dxgi_target); + IDXGISurface_Release(dxgi_surface); + if (FAILED(hr)) + { + WARN("Failed to create DXGI surface render target, hr %#x.\n", hr); + IDXGISwapChain_Release(render_target->swapchain); + return hr; + } + + return S_OK; +} diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index 6824e9f..6a8fd8e 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -2181,7 +2181,14 @@ err: return hr; } -HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *iface, IDXGISurface1 *surface) +void d2d_d3d_render_target_set_pixel_size(ID2D1RenderTarget *iface, UINT32 width, UINT32 height) +{ + struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface); + render_target->pixel_size.width = width; + render_target->pixel_size.height = height; +} + +HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *iface, IDXGISurface1 *surface) { struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface); DXGI_SURFACE_DESC surface_desc; @@ -2189,6 +2196,13 @@ HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *iface, IDXGISurf ID3D10Resource *resource; HRESULT hr; + if (!surface) + { + ID3D10RenderTargetView_Release(render_target->view); + render_target->view = NULL; + return S_OK; + } + if (FAILED(hr = IDXGISurface1_GetDesc(surface, &surface_desc))) { WARN("Failed to get surface desc, hr %#x.\n", hr); diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 91d5136..8c96071 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -2831,6 +2831,54 @@ static void test_dc_target(void) ID2D1Factory_Release(factory); } +static void test_hwnd_target(void) +{ + D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc; + D2D1_RENDER_TARGET_PROPERTIES desc; + ID2D1HwndRenderTarget *rt; + ID2D1Factory *factory; + ID3D10Device1 *device; + HRESULT hr; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + ID3D10Device1_Release(device); + + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); + ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr); + + desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + desc.dpiX = 0.0f; + desc.dpiY = 0.0f; + desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + hwnd_rt_desc.hwnd = NULL; + hwnd_rt_desc.pixelSize.width = 64; + hwnd_rt_desc.pixelSize.height = 64; + hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE; + + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + ok(FAILED(hr), "Failed to create factory, hr %#x.\n", hr); + + hwnd_rt_desc.hwnd = (HWND)0xdeadbeef; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + ok(FAILED(hr), "Failed to create factory, hr %#x.\n", hr); + + hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0); + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr); + + ID2D1HwndRenderTarget_Release(rt); + + DestroyWindow(hwnd_rt_desc.hwnd); + ID2D1Factory_Release(factory); +} + START_TEST(d2d1) { test_clip(); @@ -2846,4 +2894,5 @@ START_TEST(d2d1) test_create_target(); test_draw_text_layout(); test_dc_target(); + test_hwnd_target(); } -- 2.9.3 From nsivov at codeweavers.com Sat Oct 1 11:12:46 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Sat, 1 Oct 2016 19:12:46 +0300 Subject: [PATCH v2] d2d1: Initial implementation of HWND render target Message-ID: <20161001161246.17187-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- v2: fixed test failure dlls/d2d1/Makefile.in | 3 +- dlls/d2d1/d2d1_private.h | 19 +- dlls/d2d1/dc_render_target.c | 2 +- dlls/d2d1/factory.c | 25 +- dlls/d2d1/hwnd_render_target.c | 869 +++++++++++++++++++++++++++++++++++++++++ dlls/d2d1/render_target.c | 16 +- dlls/d2d1/tests/d2d1.c | 51 +++ 7 files changed, 979 insertions(+), 6 deletions(-) create mode 100644 dlls/d2d1/hwnd_render_target.c diff --git a/dlls/d2d1/Makefile.in b/dlls/d2d1/Makefile.in index 06f7bde..deacd7a 100644 --- a/dlls/d2d1/Makefile.in +++ b/dlls/d2d1/Makefile.in @@ -1,6 +1,6 @@ MODULE = d2d1.dll IMPORTLIB = d2d1 -IMPORTS = d3d10_1 dxguid uuid gdi32 +IMPORTS = d3d10_1 dxguid uuid gdi32 user32 DELAYIMPORTS = dwrite C_SRCS = \ @@ -9,6 +9,7 @@ C_SRCS = \ dc_render_target.c \ factory.c \ geometry.c \ + hwnd_render_target.c \ mesh.c \ render_target.c \ state_block.c \ diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index fa7e464..e893826 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -96,7 +96,9 @@ struct d2d_d3d_render_target HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory, IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN; -HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN; +HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN; +void d2d_d3d_render_target_set_pixel_size(ID2D1RenderTarget *render_target, UINT32 width, UINT32 height) + DECLSPEC_HIDDEN; struct d2d_wic_render_target { @@ -131,6 +133,21 @@ struct d2d_dc_render_target HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID2D1Factory *factory, ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN; +struct d2d_hwnd_render_target +{ + ID2D1HwndRenderTarget ID2D1HwndRenderTarget_iface; + LONG refcount; + + ID2D1RenderTarget *dxgi_target; + IDXGISwapChain *swapchain; + UINT sync_interval; + HWND hwnd; +}; + +HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target, ID2D1Factory *factory, + ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc, + const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_desc) DECLSPEC_HIDDEN; + struct d2d_gradient { ID2D1GradientStopCollection ID2D1GradientStopCollection_iface; diff --git a/dlls/d2d1/dc_render_target.c b/dlls/d2d1/dc_render_target.c index ae87a0d..1cf2c8d 100644 --- a/dlls/d2d1/dc_render_target.c +++ b/dlls/d2d1/dc_render_target.c @@ -731,7 +731,7 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget } /* Switch dxgi target to new surface. */ - if (FAILED(hr = d2d_d3d_render_target_update_surface(render_target->dxgi_target, dxgi_surface))) + if (FAILED(hr = d2d_d3d_render_target_create_rtv(render_target->dxgi_target, dxgi_surface))) { WARN("Failed to set new surface, hr %#x.\n", hr); IDXGISurface1_Release(dxgi_surface); diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 66ed25b..a31af98 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -271,9 +271,30 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory const D2D1_RENDER_TARGET_PROPERTIES *desc, const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_rt_desc, ID2D1HwndRenderTarget **render_target) { - FIXME("iface %p, desc %p, hwnd_rt_desc %p, render_target %p stub!\n", iface, desc, hwnd_rt_desc, render_target); + struct d2d_factory *factory = impl_from_ID2D1Factory(iface); + struct d2d_hwnd_render_target *object; + ID3D10Device1 *device; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, desc %p, hwnd_rt_desc %p, render_target %p\n", iface, desc, hwnd_rt_desc, render_target); + + if (FAILED(hr = d2d_factory_get_device(factory, &device))) + return hr; + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d2d_hwnd_render_target_init(object, iface, device, desc, hwnd_rt_desc))) + { + WARN("Failed to initialize render target, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + TRACE("Created render target %p.\n", object); + *render_target = &object->ID2D1HwndRenderTarget_iface; + + return S_OK; } static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDxgiSurfaceRenderTarget(ID2D1Factory *iface, diff --git a/dlls/d2d1/hwnd_render_target.c b/dlls/d2d1/hwnd_render_target.c new file mode 100644 index 0000000..e9092b6 --- /dev/null +++ b/dlls/d2d1/hwnd_render_target.c @@ -0,0 +1,869 @@ +/* + * Copyright 2014 Henri Verbeet for CodeWeavers + * Copyright 2016 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include "d2d1_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d2d); + +static void render_target_present(struct d2d_hwnd_render_target *render_target) +{ + HRESULT hr; + + if (FAILED(hr = IDXGISwapChain_Present(render_target->swapchain, render_target->sync_interval, 0))) + WARN("Present failed, %#x.\n", hr); +} + +static inline struct d2d_hwnd_render_target *impl_from_ID2D1HwndRenderTarget(ID2D1HwndRenderTarget *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_hwnd_render_target, ID2D1HwndRenderTarget_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_QueryInterface(ID2D1HwndRenderTarget *iface, + REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1HwndRenderTarget) + || IsEqualGUID(iid, &IID_ID2D1RenderTarget) + || IsEqualGUID(iid, &IID_ID2D1Resource) + || IsEqualGUID(iid, &IID_IUnknown)) + { + ID2D1HwndRenderTarget_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_hwnd_render_target_AddRef(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + ULONG refcount = InterlockedIncrement(&render_target->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_hwnd_render_target_Release(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + ULONG refcount = InterlockedDecrement(&render_target->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (!refcount) + { + ID2D1RenderTarget_Release(render_target->dxgi_target); + IDXGISwapChain_Release(render_target->swapchain); + HeapFree(GetProcessHeap(), 0, render_target); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetFactory(ID2D1HwndRenderTarget *iface, ID2D1Factory **factory) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, factory %p.\n", iface, factory); + + ID2D1RenderTarget_GetFactory(render_target->dxgi_target, factory); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateBitmap(ID2D1HwndRenderTarget *iface, + D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, size {%u, %u}, src_data %p, pitch %u, desc %p, bitmap %p.\n", + iface, size.width, size.height, src_data, pitch, desc, bitmap); + + return ID2D1RenderTarget_CreateBitmap(render_target->dxgi_target, size, src_data, pitch, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateBitmapFromWicBitmap(ID2D1HwndRenderTarget *iface, + IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, bitmap_source %p, desc %p, bitmap %p.\n", + iface, bitmap_source, desc, bitmap); + + return ID2D1RenderTarget_CreateBitmapFromWicBitmap(render_target->dxgi_target, bitmap_source, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateSharedBitmap(ID2D1HwndRenderTarget *iface, + REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, iid %s, data %p, desc %p, bitmap %p.\n", + iface, debugstr_guid(iid), data, desc, bitmap); + + return ID2D1RenderTarget_CreateSharedBitmap(render_target->dxgi_target, iid, data, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateBitmapBrush(ID2D1HwndRenderTarget *iface, + ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc, + const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1BitmapBrush **brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p.\n", + iface, bitmap, bitmap_brush_desc, brush_desc, brush); + + return ID2D1RenderTarget_CreateBitmapBrush(render_target->dxgi_target, + bitmap, bitmap_brush_desc, brush_desc, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateSolidColorBrush(ID2D1HwndRenderTarget *iface, + const D2D1_COLOR_F *color, const D2D1_BRUSH_PROPERTIES *desc, ID2D1SolidColorBrush **brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, color %p, desc %p, brush %p.\n", iface, color, desc, brush); + + return ID2D1RenderTarget_CreateSolidColorBrush(render_target->dxgi_target, color, desc, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateGradientStopCollection(ID2D1HwndRenderTarget *iface, + const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode, + ID2D1GradientStopCollection **gradient) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n", + iface, stops, stop_count, gamma, extend_mode, gradient); + + return ID2D1RenderTarget_CreateGradientStopCollection(render_target->dxgi_target, + stops, stop_count, gamma, extend_mode, gradient); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateLinearGradientBrush(ID2D1HwndRenderTarget *iface, + const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1GradientStopCollection *gradient, ID2D1LinearGradientBrush **brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n", + iface, gradient_brush_desc, brush_desc, gradient, brush); + + return ID2D1RenderTarget_CreateLinearGradientBrush(render_target->dxgi_target, + gradient_brush_desc, brush_desc, gradient, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateRadialGradientBrush(ID2D1HwndRenderTarget *iface, + const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1GradientStopCollection *gradient, ID2D1RadialGradientBrush **brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n", + iface, gradient_brush_desc, brush_desc, gradient, brush); + + return ID2D1RenderTarget_CreateRadialGradientBrush(render_target->dxgi_target, + gradient_brush_desc, brush_desc, gradient, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateCompatibleRenderTarget(ID2D1HwndRenderTarget *iface, + const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **render_target) +{ + struct d2d_hwnd_render_target *rt = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p,\n", + iface, size, pixel_size, format, options, render_target); + + return ID2D1RenderTarget_CreateCompatibleRenderTarget(rt->dxgi_target, + size, pixel_size, format, options, render_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateLayer(ID2D1HwndRenderTarget *iface, + const D2D1_SIZE_F *size, ID2D1Layer **layer) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, size %p, layer %p.\n", iface, size, layer); + + return ID2D1RenderTarget_CreateLayer(render_target->dxgi_target, size, layer); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateMesh(ID2D1HwndRenderTarget *iface, ID2D1Mesh **mesh) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, mesh %p.\n", iface, mesh); + + return ID2D1RenderTarget_CreateMesh(render_target->dxgi_target, mesh); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawLine(ID2D1HwndRenderTarget *iface, + D2D1_POINT_2F p0, D2D1_POINT_2F p1, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, p0 {%.8e, %.8e}, p1 {%.8e, %.8e}, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, p0.x, p0.y, p1.x, p1.y, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawLine(render_target->dxgi_target, p0, p1, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawRectangle(ID2D1HwndRenderTarget *iface, + const D2D1_RECT_F *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, rect, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawRectangle(render_target->dxgi_target, rect, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillRectangle(ID2D1HwndRenderTarget *iface, + const D2D1_RECT_F *rect, ID2D1Brush *brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p.\n", iface, rect, brush); + + ID2D1RenderTarget_FillRectangle(render_target->dxgi_target, rect, brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawRoundedRectangle(ID2D1HwndRenderTarget *iface, + const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, rect, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawRoundedRectangle(render_target->dxgi_target, rect, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillRoundedRectangle(ID2D1HwndRenderTarget *iface, + const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p.\n", iface, rect, brush); + + ID2D1RenderTarget_FillRoundedRectangle(render_target->dxgi_target, rect, brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawEllipse(ID2D1HwndRenderTarget *iface, + const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, ellipse %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, ellipse, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawEllipse(render_target->dxgi_target, ellipse, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillEllipse(ID2D1HwndRenderTarget *iface, + const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, ellipse %p, brush %p.\n", iface, ellipse, brush); + + ID2D1RenderTarget_FillEllipse(render_target->dxgi_target, ellipse, brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawGeometry(ID2D1HwndRenderTarget *iface, + ID2D1Geometry *geometry, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, geometry %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, geometry, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawGeometry(render_target->dxgi_target, geometry, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillGeometry(ID2D1HwndRenderTarget *iface, + ID2D1Geometry *geometry, ID2D1Brush *brush, ID2D1Brush *opacity_brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, geometry %p, brush %p, opacity_brush %p.\n", iface, geometry, brush, opacity_brush); + + ID2D1RenderTarget_FillGeometry(render_target->dxgi_target, geometry, brush, opacity_brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillMesh(ID2D1HwndRenderTarget *iface, + ID2D1Mesh *mesh, ID2D1Brush *brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, mesh %p, brush %p.\n", iface, mesh, brush); + + ID2D1RenderTarget_FillMesh(render_target->dxgi_target, mesh, brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillOpacityMask(ID2D1HwndRenderTarget *iface, + ID2D1Bitmap *mask, ID2D1Brush *brush, D2D1_OPACITY_MASK_CONTENT content, + const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, mask %p, brush %p, content %#x, dst_rect %p, src_rect %p.\n", + iface, mask, brush, content, dst_rect, src_rect); + + ID2D1RenderTarget_FillOpacityMask(render_target->dxgi_target, + mask, brush, content, dst_rect, src_rect); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawBitmap(ID2D1HwndRenderTarget *iface, + ID2D1Bitmap *bitmap, const D2D1_RECT_F *dst_rect, float opacity, + D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, const D2D1_RECT_F *src_rect) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, bitmap %p, dst_rect %p, opacity %.8e, interpolation_mode %#x, src_rect %p.\n", + iface, bitmap, dst_rect, opacity, interpolation_mode, src_rect); + + ID2D1RenderTarget_DrawBitmap(render_target->dxgi_target, + bitmap, dst_rect, opacity, interpolation_mode, src_rect); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawText(ID2D1HwndRenderTarget *iface, + const WCHAR *string, UINT32 string_len, IDWriteTextFormat *text_format, const D2D1_RECT_F *layout_rect, + ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuring_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, string %s, string_len %u, text_format %p, layout_rect %p, " + "brush %p, options %#x, measuring_mode %#x.\n", + iface, debugstr_wn(string, string_len), string_len, text_format, layout_rect, + brush, options, measuring_mode); + + ID2D1RenderTarget_DrawText(render_target->dxgi_target, string, string_len, + text_format, layout_rect, brush, options, measuring_mode); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawTextLayout(ID2D1HwndRenderTarget *iface, + D2D1_POINT_2F origin, IDWriteTextLayout *layout, ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, origin {%.8e, %.8e}, layout %p, brush %p, options %#x.\n", + iface, origin.x, origin.y, layout, brush, options); + + ID2D1RenderTarget_DrawTextLayout(render_target->dxgi_target, origin, layout, brush, options); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawGlyphRun(ID2D1HwndRenderTarget *iface, + D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush, + DWRITE_MEASURING_MODE measuring_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, baseline_origin {%.8e, %.8e}, glyph_run %p, brush %p, measuring_mode %#x.\n", + iface, baseline_origin.x, baseline_origin.y, glyph_run, brush, measuring_mode); + + ID2D1RenderTarget_DrawGlyphRun(render_target->dxgi_target, + baseline_origin, glyph_run, brush, measuring_mode); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetTransform(ID2D1HwndRenderTarget *iface, + const D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, transform %p.\n", iface, transform); + + ID2D1RenderTarget_SetTransform(render_target->dxgi_target, transform); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetTransform(ID2D1HwndRenderTarget *iface, + D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, transform %p.\n", iface, transform); + + ID2D1RenderTarget_GetTransform(render_target->dxgi_target, transform); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetAntialiasMode(ID2D1HwndRenderTarget *iface, + D2D1_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, antialias_mode %#x.\n", iface, antialias_mode); + + ID2D1RenderTarget_SetAntialiasMode(render_target->dxgi_target, antialias_mode); +} + +static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_hwnd_render_target_GetAntialiasMode(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetAntialiasMode(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetTextAntialiasMode(ID2D1HwndRenderTarget *iface, + D2D1_TEXT_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, antialias_mode %#x.\n", iface, antialias_mode); + + ID2D1RenderTarget_SetTextAntialiasMode(render_target->dxgi_target, antialias_mode); +} + +static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_hwnd_render_target_GetTextAntialiasMode( + ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetTextAntialiasMode(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetTextRenderingParams(ID2D1HwndRenderTarget *iface, + IDWriteRenderingParams *text_rendering_params) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params); + + ID2D1RenderTarget_SetTextRenderingParams(render_target->dxgi_target, text_rendering_params); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetTextRenderingParams(ID2D1HwndRenderTarget *iface, + IDWriteRenderingParams **text_rendering_params) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params); + + ID2D1RenderTarget_GetTextRenderingParams(render_target->dxgi_target, text_rendering_params); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetTags(ID2D1HwndRenderTarget *iface, D2D1_TAG tag1, D2D1_TAG tag2) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, tag1 %s, tag2 %s.\n", iface, wine_dbgstr_longlong(tag1), wine_dbgstr_longlong(tag2)); + + ID2D1RenderTarget_SetTags(render_target->dxgi_target, tag1, tag2); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetTags(ID2D1HwndRenderTarget *iface, D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + ID2D1RenderTarget_GetTags(render_target->dxgi_target, tag1, tag2); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_PushLayer(ID2D1HwndRenderTarget *iface, + const D2D1_LAYER_PARAMETERS *layer_parameters, ID2D1Layer *layer) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, layer_parameters %p, layer %p.\n", iface, layer_parameters, layer); + + ID2D1RenderTarget_PushLayer(render_target->dxgi_target, layer_parameters, layer); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_PopLayer(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_PopLayer(render_target->dxgi_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_Flush(ID2D1HwndRenderTarget *iface, D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + HRESULT hr; + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + hr = ID2D1RenderTarget_Flush(render_target->dxgi_target, tag1, tag2); + render_target_present(render_target); + + return hr; +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SaveDrawingState(ID2D1HwndRenderTarget *iface, + ID2D1DrawingStateBlock *state_block) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, state_block %p.\n", iface, state_block); + + ID2D1RenderTarget_SaveDrawingState(render_target->dxgi_target, state_block); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_RestoreDrawingState(ID2D1HwndRenderTarget *iface, + ID2D1DrawingStateBlock *state_block) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, state_block %p.\n", iface, state_block); + + ID2D1RenderTarget_RestoreDrawingState(render_target->dxgi_target, state_block); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_PushAxisAlignedClip(ID2D1HwndRenderTarget *iface, + const D2D1_RECT_F *clip_rect, D2D1_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, clip_rect %p, antialias_mode %#x.\n", iface, clip_rect, antialias_mode); + + ID2D1RenderTarget_PushAxisAlignedClip(render_target->dxgi_target, clip_rect, antialias_mode); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_PopAxisAlignedClip(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_PopAxisAlignedClip(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_Clear(ID2D1HwndRenderTarget *iface, const D2D1_COLOR_F *color) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, color %p.\n", iface, color); + + ID2D1RenderTarget_Clear(render_target->dxgi_target, color); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_BeginDraw(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_BeginDraw(render_target->dxgi_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_EndDraw(ID2D1HwndRenderTarget *iface, + D2D1_TAG *tag1, D2D1_TAG *tag2) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + HRESULT hr; + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + hr = ID2D1RenderTarget_EndDraw(render_target->dxgi_target, tag1, tag2); + render_target_present(render_target); + + return hr; +} + +static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_hwnd_render_target_GetPixelFormat(ID2D1HwndRenderTarget *iface, + D2D1_PIXEL_FORMAT *format) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, format %p.\n", iface, format); + + *format = ID2D1RenderTarget_GetPixelFormat(render_target->dxgi_target); + return format; +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetDpi(ID2D1HwndRenderTarget *iface, float dpi_x, float dpi_y) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, dpi_x %.8e, dpi_y %.8e.\n", iface, dpi_x, dpi_y); + + ID2D1RenderTarget_SetDpi(render_target->dxgi_target, dpi_x, dpi_y); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetDpi(ID2D1HwndRenderTarget *iface, float *dpi_x, float *dpi_y) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y); + + ID2D1RenderTarget_GetDpi(render_target->dxgi_target, dpi_x, dpi_y); +} + +static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_hwnd_render_target_GetSize(ID2D1HwndRenderTarget *iface, D2D1_SIZE_F *size) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, size %p.\n", iface, size); + + *size = ID2D1RenderTarget_GetSize(render_target->dxgi_target); + return size; +} + +static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_hwnd_render_target_GetPixelSize(ID2D1HwndRenderTarget *iface, + D2D1_SIZE_U *pixel_size) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, pixel_size %p.\n", iface, pixel_size); + + *pixel_size = ID2D1RenderTarget_GetPixelSize(render_target->dxgi_target); + return pixel_size; +} + +static UINT32 STDMETHODCALLTYPE d2d_hwnd_render_target_GetMaximumBitmapSize(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetMaximumBitmapSize(render_target->dxgi_target); +} + +static BOOL STDMETHODCALLTYPE d2d_hwnd_render_target_IsSupported(ID2D1HwndRenderTarget *iface, + const D2D1_RENDER_TARGET_PROPERTIES *desc) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + return ID2D1RenderTarget_IsSupported(render_target->dxgi_target, desc); +} + +static D2D1_WINDOW_STATE STDMETHODCALLTYPE d2d_hwnd_render_target_CheckWindowState(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return IDXGISwapChain_Present(render_target->swapchain, render_target->sync_interval, DXGI_PRESENT_TEST) == + DXGI_STATUS_OCCLUDED ? D2D1_WINDOW_STATE_OCCLUDED : D2D1_WINDOW_STATE_NONE; +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_Resize(ID2D1HwndRenderTarget *iface, const D2D1_SIZE_U size) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + IDXGISurface1 *dxgi_surface; + HRESULT hr; + + TRACE("iface %p, width %u, height %u.\n", iface, size.width, size.height); + + d2d_d3d_render_target_create_rtv(render_target->dxgi_target, NULL); + + if (SUCCEEDED(hr = IDXGISwapChain_ResizeBuffers(render_target->swapchain, 1, size.width, size.height, + DXGI_FORMAT_UNKNOWN, 0))) + { + if (FAILED(hr = IDXGISwapChain_GetBuffer(render_target->swapchain, 0, &IID_IDXGISurface1, + (void **)&dxgi_surface))) + { + WARN("Failed to get buffer, hr %#x.\n", hr); + return hr; + } + + hr = d2d_d3d_render_target_create_rtv(render_target->dxgi_target, dxgi_surface); + IDXGISurface1_Release(dxgi_surface); + } + + return hr; +} + +static HWND STDMETHODCALLTYPE d2d_hwnd_render_target_GetHwnd(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return render_target->hwnd; +} + +static const struct ID2D1HwndRenderTargetVtbl d2d_hwnd_render_target_vtbl = +{ + d2d_hwnd_render_target_QueryInterface, + d2d_hwnd_render_target_AddRef, + d2d_hwnd_render_target_Release, + d2d_hwnd_render_target_GetFactory, + d2d_hwnd_render_target_CreateBitmap, + d2d_hwnd_render_target_CreateBitmapFromWicBitmap, + d2d_hwnd_render_target_CreateSharedBitmap, + d2d_hwnd_render_target_CreateBitmapBrush, + d2d_hwnd_render_target_CreateSolidColorBrush, + d2d_hwnd_render_target_CreateGradientStopCollection, + d2d_hwnd_render_target_CreateLinearGradientBrush, + d2d_hwnd_render_target_CreateRadialGradientBrush, + d2d_hwnd_render_target_CreateCompatibleRenderTarget, + d2d_hwnd_render_target_CreateLayer, + d2d_hwnd_render_target_CreateMesh, + d2d_hwnd_render_target_DrawLine, + d2d_hwnd_render_target_DrawRectangle, + d2d_hwnd_render_target_FillRectangle, + d2d_hwnd_render_target_DrawRoundedRectangle, + d2d_hwnd_render_target_FillRoundedRectangle, + d2d_hwnd_render_target_DrawEllipse, + d2d_hwnd_render_target_FillEllipse, + d2d_hwnd_render_target_DrawGeometry, + d2d_hwnd_render_target_FillGeometry, + d2d_hwnd_render_target_FillMesh, + d2d_hwnd_render_target_FillOpacityMask, + d2d_hwnd_render_target_DrawBitmap, + d2d_hwnd_render_target_DrawText, + d2d_hwnd_render_target_DrawTextLayout, + d2d_hwnd_render_target_DrawGlyphRun, + d2d_hwnd_render_target_SetTransform, + d2d_hwnd_render_target_GetTransform, + d2d_hwnd_render_target_SetAntialiasMode, + d2d_hwnd_render_target_GetAntialiasMode, + d2d_hwnd_render_target_SetTextAntialiasMode, + d2d_hwnd_render_target_GetTextAntialiasMode, + d2d_hwnd_render_target_SetTextRenderingParams, + d2d_hwnd_render_target_GetTextRenderingParams, + d2d_hwnd_render_target_SetTags, + d2d_hwnd_render_target_GetTags, + d2d_hwnd_render_target_PushLayer, + d2d_hwnd_render_target_PopLayer, + d2d_hwnd_render_target_Flush, + d2d_hwnd_render_target_SaveDrawingState, + d2d_hwnd_render_target_RestoreDrawingState, + d2d_hwnd_render_target_PushAxisAlignedClip, + d2d_hwnd_render_target_PopAxisAlignedClip, + d2d_hwnd_render_target_Clear, + d2d_hwnd_render_target_BeginDraw, + d2d_hwnd_render_target_EndDraw, + d2d_hwnd_render_target_GetPixelFormat, + d2d_hwnd_render_target_SetDpi, + d2d_hwnd_render_target_GetDpi, + d2d_hwnd_render_target_GetSize, + d2d_hwnd_render_target_GetPixelSize, + d2d_hwnd_render_target_GetMaximumBitmapSize, + d2d_hwnd_render_target_IsSupported, + d2d_hwnd_render_target_CheckWindowState, + d2d_hwnd_render_target_Resize, + d2d_hwnd_render_target_GetHwnd +}; + +HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target, ID2D1Factory *factory, + ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc, + const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_rt_desc) +{ + D2D1_RENDER_TARGET_PROPERTIES dxgi_rt_desc; + DXGI_SWAP_CHAIN_DESC swapchain_desc; + IDXGIAdapter *dxgi_adapter; + IDXGIFactory *dxgi_factory; + IDXGISurface *dxgi_surface; + IDXGIDevice *dxgi_device; + HRESULT hr; + + if (!IsWindow(hwnd_rt_desc->hwnd)) + return HRESULT_FROM_WIN32(ERROR_INVALID_WINDOW_HANDLE); + + render_target->ID2D1HwndRenderTarget_iface.lpVtbl = &d2d_hwnd_render_target_vtbl; + render_target->refcount = 1; + render_target->hwnd = hwnd_rt_desc->hwnd; + render_target->sync_interval = hwnd_rt_desc->presentOptions & D2D1_PRESENT_OPTIONS_IMMEDIATELY ? 0 : 1; + + if (FAILED(hr = ID3D10Device1_QueryInterface(device, &IID_IDXGIDevice, (void **)&dxgi_device))) + { + WARN("Failed to get IDXGIDevice interface, hr %#x.\n", hr); + return hr; + } + + hr = IDXGIDevice_GetAdapter(dxgi_device, &dxgi_adapter); + IDXGIDevice_Release(dxgi_device); + if (FAILED(hr)) + { + WARN("Failed to get IDXGIAdapter interface, hr %#x.\n", hr); + return hr; + } + + hr = IDXGIAdapter_GetParent(dxgi_adapter, &IID_IDXGIFactory, (void **)&dxgi_factory); + IDXGIAdapter_Release(dxgi_adapter); + if (FAILED(hr)) + { + WARN("Failed to get IDXGIFactory interface, hr %#x.\n", hr); + return hr; + } + + dxgi_rt_desc = *desc; + if (dxgi_rt_desc.dpiX == 0.0f && dxgi_rt_desc.dpiY == 0.0f) + ID2D1Factory_GetDesktopDpi(factory, &dxgi_rt_desc.dpiX, &dxgi_rt_desc.dpiY); + + if (dxgi_rt_desc.pixelFormat.format == DXGI_FORMAT_UNKNOWN) + { + dxgi_rt_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + dxgi_rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE; + } + + swapchain_desc.BufferDesc.Width = hwnd_rt_desc->pixelSize.width; + swapchain_desc.BufferDesc.Height = hwnd_rt_desc->pixelSize.height; + swapchain_desc.BufferDesc.RefreshRate.Numerator = 60; + swapchain_desc.BufferDesc.RefreshRate.Denominator = 1; + swapchain_desc.BufferDesc.Format = dxgi_rt_desc.pixelFormat.format; + swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + swapchain_desc.SampleDesc.Count = 1; + swapchain_desc.SampleDesc.Quality = 0; + swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapchain_desc.BufferCount = 1; + swapchain_desc.OutputWindow = hwnd_rt_desc->hwnd; + swapchain_desc.Windowed = TRUE; + swapchain_desc.SwapEffect = hwnd_rt_desc->presentOptions & D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS ? + DXGI_SWAP_EFFECT_SEQUENTIAL : DXGI_SWAP_EFFECT_DISCARD; + swapchain_desc.Flags = 0; + + hr = IDXGIFactory_CreateSwapChain(dxgi_factory, (IUnknown *)device, &swapchain_desc, &render_target->swapchain); + IDXGIFactory_Release(dxgi_factory); + if (FAILED(hr)) + { + WARN("Failed to create a swapchain, hr %#x.\n", hr); + return hr; + } + + if (FAILED(hr = IDXGISwapChain_GetBuffer(render_target->swapchain, 0, &IID_IDXGISurface, (void **)&dxgi_surface))) + { + WARN("Failed to get buffer, hr %#x.\n", hr); + IDXGISwapChain_Release(render_target->swapchain); + return hr; + } + + hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, dxgi_surface, &dxgi_rt_desc, &render_target->dxgi_target); + IDXGISurface_Release(dxgi_surface); + if (FAILED(hr)) + { + WARN("Failed to create DXGI surface render target, hr %#x.\n", hr); + IDXGISwapChain_Release(render_target->swapchain); + return hr; + } + + return S_OK; +} diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index 6824e9f..6a8fd8e 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -2181,7 +2181,14 @@ err: return hr; } -HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *iface, IDXGISurface1 *surface) +void d2d_d3d_render_target_set_pixel_size(ID2D1RenderTarget *iface, UINT32 width, UINT32 height) +{ + struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface); + render_target->pixel_size.width = width; + render_target->pixel_size.height = height; +} + +HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *iface, IDXGISurface1 *surface) { struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface); DXGI_SURFACE_DESC surface_desc; @@ -2189,6 +2196,13 @@ HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *iface, IDXGISurf ID3D10Resource *resource; HRESULT hr; + if (!surface) + { + ID3D10RenderTargetView_Release(render_target->view); + render_target->view = NULL; + return S_OK; + } + if (FAILED(hr = IDXGISurface1_GetDesc(surface, &surface_desc))) { WARN("Failed to get surface desc, hr %#x.\n", hr); diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 91d5136..c9e1692 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -2831,6 +2831,56 @@ static void test_dc_target(void) ID2D1Factory_Release(factory); } +static void test_hwnd_target(void) +{ + D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc; + D2D1_RENDER_TARGET_PROPERTIES desc; + ID2D1HwndRenderTarget *rt; + ID2D1Factory *factory; + ID3D10Device1 *device; + HRESULT hr; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + ID3D10Device1_Release(device); + + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); + ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr); + + desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + desc.dpiX = 0.0f; + desc.dpiY = 0.0f; + desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + hwnd_rt_desc.hwnd = NULL; + hwnd_rt_desc.pixelSize.width = 64; + hwnd_rt_desc.pixelSize.height = 64; + hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE; + + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + ok(FAILED(hr), "Target creation should fail, hr %#x.\n", hr); + + hwnd_rt_desc.hwnd = (HWND)0xdeadbeef; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + ok(FAILED(hr), "Target creation should fail, hr %#x.\n", hr); + + hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0); + ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n"); + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + ID2D1HwndRenderTarget_Release(rt); + + DestroyWindow(hwnd_rt_desc.hwnd); + ID2D1Factory_Release(factory); +} + START_TEST(d2d1) { test_clip(); @@ -2846,4 +2896,5 @@ START_TEST(d2d1) test_create_target(); test_draw_text_layout(); test_dc_target(); + test_hwnd_target(); } -- 2.9.3 From stefandoesinger at gmx.at Sat Oct 1 12:39:27 2016 From: stefandoesinger at gmx.at (=?UTF-8?q?Stefan=20D=C3=B6singer?=) Date: Sat, 1 Oct 2016 18:39:27 +0100 Subject: [PATCH 1/6] ddraw/tests: Add position tests for D3DPROCESSVERTICES_TRANSFORM (v2). Message-ID: <1475343572-5997-1-git-send-email-stefandoesinger@gmx.at> Version 2: Don't validate the clear rectangle. AMD drivers have problems with clipping the clear to the viewport dimensions (see e.g. 60f62f4d, although no culled draw seems to be needed for this to fail here), and it isn't really the purpose of this test anyway. Signed-off-by: Stefan Dösinger --- dlls/ddraw/tests/ddraw1.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 1271022..207ee59 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -9125,12 +9125,15 @@ struct transform_output static void test_transform_vertices(void) { IDirect3DDevice *device; + IDirectDrawSurface *rt; IDirectDraw *ddraw; ULONG refcount; HWND window; HRESULT hr; + D3DCOLOR color; IDirect3DViewport *viewport; IDirect3DExecuteBuffer *execute_buffer; + IDirect3DMaterial *background; D3DEXECUTEBUFFERDESC exec_desc; UINT inst_length; void *ptr; @@ -9189,6 +9192,14 @@ static void test_transform_vertices(void) 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, }; + static const D3DLVERTEX quad[] = + { + {{-0.75f},{-0.5f }, {0.0f}, 0, {0xffff0000}}, + {{-0.75f},{ 0.25f}, {0.0f}, 0, {0xffff0000}}, + {{ 0.5f}, {-0.5f }, {0.0f}, 0, {0xffff0000}}, + {{ 0.5f}, { 0.25f}, {0.0f}, 0, {0xffff0000}}, + }; + static D3DRECT clear_rect = {{0}, {0}, {640}, {480}}; for (i = 0; i < ARRAY_SIZE(out); ++i) @@ -9209,6 +9220,9 @@ static void test_transform_vertices(void) return; } + hr = IDirect3DDevice_QueryInterface(device, &IID_IDirectDrawSurface, (void **)&rt); + ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); + viewport = create_viewport(device, 0, 0, 256, 256); hr = IDirect3DViewport_SetViewport(viewport, &vp_data); ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr); @@ -9600,12 +9614,68 @@ static void test_transform_vertices(void) ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr); ok(offscreen == ~0U, "Offscreen is %x.\n", offscreen); + /* Test how vertices are transformed by execute buffers. */ + vp_data.dwX = 20; + vp_data.dwY = 20; + vp_data.dwWidth = 200; + vp_data.dwHeight = 400; + vp_data.dvScaleX = 20.0f; + vp_data.dvScaleY = 50.0f; + vp_data.dvMinZ = 0.0f; + vp_data.dvMaxZ = 1.0f; + hr = IDirect3DViewport_SetViewport(viewport, &vp_data); + ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr); + + background = create_diffuse_material(device, 0.0f, 0.0f, 1.0f, 0.0f); + viewport_set_background(device, viewport, background); + hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET); + ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr); + + hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc); + ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr); + memcpy(exec_desc.lpData, quad, sizeof(quad)); + ptr = ((BYTE *)exec_desc.lpData) + sizeof(quad); + emit_process_vertices(&ptr, D3DPROCESSVERTICES_TRANSFORM, 0, 4); + emit_tquad(&ptr, 0); + emit_end(&ptr); + inst_length = (BYTE *)ptr - (BYTE *)exec_desc.lpData; + hr = IDirect3DExecuteBuffer_Unlock(execute_buffer); + ok(SUCCEEDED(hr), "Failed to unlock execute buffer, hr %#x.\n", hr); + + set_execute_data(execute_buffer, 4, sizeof(quad), inst_length); + hr = IDirect3DDevice_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED); + ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x.\n", hr); + hr = IDirect3DDevice_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + + color = get_surface_color(rt, 128, 143); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 132, 143); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 128, 147); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 132, 147); + todo_wine ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); + + color = get_surface_color(rt, 177, 217); + todo_wine ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 181, 217); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 177, 221); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 181, 221); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + IDirect3DDevice_DeleteMatrix(device, world_handle); IDirect3DDevice_DeleteMatrix(device, view_handle); IDirect3DDevice_DeleteMatrix(device, proj_handle); IDirect3DExecuteBuffer_Release(execute_buffer); + IDirectDrawSurface_Release(rt); destroy_viewport(device, viewport); + IDirect3DMaterial_Release(background); refcount = IDirect3DDevice_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); IDirectDraw_Release(ddraw); -- 2.7.3 From stefandoesinger at gmx.at Sat Oct 1 12:39:29 2016 From: stefandoesinger at gmx.at (=?UTF-8?q?Stefan=20D=C3=B6singer?=) Date: Sat, 1 Oct 2016 18:39:29 +0100 Subject: [PATCH 3/6] ddraw/tests: Test d3d2 and 3 drawing with non-standard viewports (v2). In-Reply-To: <1475343572-5997-1-git-send-email-stefandoesinger@gmx.at> References: <1475343572-5997-1-git-send-email-stefandoesinger@gmx.at> Message-ID: <1475343572-5997-3-git-send-email-stefandoesinger@gmx.at> The clipped clear actually works here on AMD, but I've removed it to stay in sync with the ddraw1 version. Signed-off-by: Stefan Dösinger --- dlls/ddraw/tests/ddraw2.c | 60 +++++++++++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw4.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index bf012e4..65376b3 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -10507,11 +10507,14 @@ struct transform_output static void test_transform_vertices(void) { IDirect3DDevice2 *device; + IDirectDrawSurface *rt; IDirectDraw2 *ddraw; ULONG refcount; HWND window; HRESULT hr; + D3DCOLOR color; IDirect3DViewport2 *viewport; + IDirect3DMaterial2 *background; static struct transform_input position_tests[] = { { 0.0f, 0.0f, 0.0f, 0.0f, 1, 2, 3, 4, 5}, @@ -10566,6 +10569,14 @@ static void test_transform_vertices(void) 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, }; + static D3DLVERTEX quad[] = + { + {{-0.75f},{-0.5f }, {0.0f}, 0, {0xffff0000}}, + {{-0.75f},{ 0.25f}, {0.0f}, 0, {0xffff0000}}, + {{ 0.5f}, {-0.5f }, {0.0f}, 0, {0xffff0000}}, + {{ 0.5f}, { 0.25f}, {0.0f}, 0, {0xffff0000}}, + }; + static D3DRECT clear_rect = {{0}, {0}, {640}, {480}}; for (i = 0; i < ARRAY_SIZE(out); ++i) @@ -10585,6 +10596,8 @@ static void test_transform_vertices(void) DestroyWindow(window); return; } + hr = IDirect3DDevice2_GetRenderTarget(device, &rt); + ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); viewport = create_viewport(device, 0, 0, 256, 256); hr = IDirect3DViewport2_SetViewport(viewport, &vp_data); @@ -10942,7 +10955,54 @@ static void test_transform_vertices(void) ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr); ok(offscreen == ~0U, "Offscreen is %x.\n", offscreen); + /* Test how vertices are transformed during draws. */ + vp_data.dwX = 20; + vp_data.dwY = 20; + vp_data.dwWidth = 200; + vp_data.dwHeight = 400; + vp_data.dvScaleX = 20.0f; + vp_data.dvScaleY = 50.0f; + vp_data.dvMinZ = 0.0f; + vp_data.dvMaxZ = 1.0f; + hr = IDirect3DViewport2_SetViewport(viewport, &vp_data); + ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr); + hr = IDirect3DDevice2_SetCurrentViewport(device, viewport); + ok(SUCCEEDED(hr), "Failed to activate the viewport, hr %#x.\n", hr); + + ok(SUCCEEDED(hr), "Failed to clear the render target, hr %#x.\n", hr); + background = create_diffuse_material(device, 0.0f, 0.0f, 1.0f, 0.0f); + viewport_set_background(device, viewport, background); + hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET); + ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr); + + hr = IDirect3DDevice2_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice2_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DVT_LVERTEX, quad, 4, 0); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice2_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + + color = get_surface_color(rt, 128, 143); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 132, 143); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 128, 147); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 132, 147); + todo_wine ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); + + color = get_surface_color(rt, 177, 217); + ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 181, 217); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 177, 221); + todo_wine ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 181, 221); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + + IDirectDrawSurface_Release(rt); destroy_viewport(device, viewport); + IDirect3DMaterial2_Release(background); refcount = IDirect3DDevice_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); IDirectDraw2_Release(ddraw); diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 9ac7a63..66301b5 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -11809,9 +11809,11 @@ struct transform_output static void test_transform_vertices(void) { IDirect3DDevice3 *device; + IDirectDrawSurface4 *rt; ULONG refcount; HWND window; HRESULT hr; + D3DCOLOR color; IDirect3DViewport3 *viewport; static struct transform_input position_tests[] = { @@ -11867,7 +11869,19 @@ static void test_transform_vertices(void) 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, }; - + static struct + { + struct vec3 position; + DWORD color; + } + quad[] = + { + {{-0.75f, -0.5f , 0.0f}, 0xffff0000}, + {{-0.75f, 0.25f, 0.0f}, 0xffff0000}, + {{ 0.5f, -0.5f , 0.0f}, 0xffff0000}, + {{ 0.5f, 0.25f, 0.0f}, 0xffff0000}, + }; + static D3DRECT clear_rect = {{0}, {0}, {640}, {480}}; for (i = 0; i < ARRAY_SIZE(out); ++i) { @@ -11883,6 +11897,8 @@ static void test_transform_vertices(void) DestroyWindow(window); return; } + hr = IDirect3DDevice3_GetRenderTarget(device, &rt); + ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); viewport = create_viewport(device, 0, 0, 256, 256); hr = IDirect3DViewport2_SetViewport(viewport, &vp_data); @@ -12240,7 +12256,51 @@ static void test_transform_vertices(void) ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr); ok(offscreen == ~0U, "Offscreen is %x.\n", offscreen); + /* Test how vertices are transformed during draws. */ + vp_data.dwX = 20; + vp_data.dwY = 20; + vp_data.dwWidth = 200; + vp_data.dwHeight = 400; + vp_data.dvScaleX = 20.0f; + vp_data.dvScaleY = 50.0f; + vp_data.dvMinZ = 0.0f; + vp_data.dvMaxZ = 1.0f; + hr = IDirect3DViewport3_SetViewport(viewport, &vp_data); + ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr); + hr = IDirect3DDevice3_SetCurrentViewport(device, viewport); + ok(SUCCEEDED(hr), "Failed to activate the viewport, hr %#x.\n", hr); + + hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0); + ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr); + + hr = IDirect3DDevice3_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, + quad, 4, 0); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice3_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + + color = get_surface_color(rt, 128, 143); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 132, 143); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 128, 147); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 132, 147); + ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); + + color = get_surface_color(rt, 177, 217); + ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 181, 217); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 177, 221); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 181, 221); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + destroy_viewport(device, viewport); + IDirectDrawSurface4_Release(rt); refcount = IDirect3DDevice3_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); DestroyWindow(window); -- 2.7.3 From stefandoesinger at gmx.at Sat Oct 1 12:39:28 2016 From: stefandoesinger at gmx.at (=?UTF-8?q?Stefan=20D=C3=B6singer?=) Date: Sat, 1 Oct 2016 18:39:28 +0100 Subject: [PATCH 2/6] ddraw: Store d3d1 projection matrices in device->legacy_projection. In-Reply-To: <1475343572-5997-1-git-send-email-stefandoesinger@gmx.at> References: <1475343572-5997-1-git-send-email-stefandoesinger@gmx.at> Message-ID: <1475343572-5997-2-git-send-email-stefandoesinger@gmx.at> The math in transform_vertex is now the same as in wined3d's process_vertices_strided. Calling wined3d_device_process_vertices is easier now, but that will require moving the vertex and index data into buffers. Signed-off-by: Stefan Dösinger --- dlls/ddraw/executebuffer.c | 13 +++++++------ dlls/ddraw/tests/ddraw1.c | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index fb52ffd..3becf58 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -56,10 +56,11 @@ static void transform_vertex(D3DTLVERTEX *dst, const D3DMATRIX *mat, dst->u3.sz = (x * mat->_13) + (y * mat->_23) + (z * mat->_33) + mat->_43; dst->u4.rhw = (x * mat->_14) + (y * mat->_24) + (z * mat->_34) + mat->_44; - dst->u1.sx = dst->u1.sx / dst->u4.rhw * vp->dvScaleX + vp->dwX + vp->dwWidth / 2; - dst->u2.sy = -dst->u2.sy / dst->u4.rhw * vp->dvScaleY + vp->dwY + vp->dwHeight / 2; - dst->u3.sz /= dst->u4.rhw; dst->u4.rhw = 1.0f / dst->u4.rhw; + + dst->u1.sx = (dst->u1.sx * dst->u4.rhw + 1.0f) * vp->dwWidth * 0.5 + vp->dwX; + dst->u2.sy = (-dst->u2.sy * dst->u4.rhw + 1.0f) * vp->dwHeight * 0.5 + vp->dwY; + dst->u3.sz *= dst->u4.rhw; } HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, @@ -203,7 +204,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, device->view = ci->u2.dwArg[0]; if (ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_PROJECTION) device->proj = ci->u2.dwArg[0]; - IDirect3DDevice7_SetTransform(&device->IDirect3DDevice7_iface, + IDirect3DDevice3_SetTransform(&device->IDirect3DDevice3_iface, ci->u1.dtstTransformStateType, m); } @@ -247,8 +248,8 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, TRACE("PROCESSVERTICES (%d)\n", count); - /* Get the transform and world matrix */ - /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */ + /* Note that the projection set in wined3d has the legacy clip space + * adjustment built in. */ wined3d_device_get_transform(device->wined3d_device, D3DTRANSFORMSTATE_VIEW, (struct wined3d_matrix *)&view_mat); wined3d_device_get_transform(device->wined3d_device, diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 207ee59..7824a92 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -9552,7 +9552,7 @@ static void test_transform_vertices(void) {143.0f, 118.0f, 1.0f, 1.0f}, {133.0f, 128.0f, -1.0f, 1.0f}, {133.0f, 128.0f, 0.0f, 1.0f} }; - todo_wine ok(compare_vec4(&cmp[i], out[i].x, out[i].y, out[i].z, out[i].w, 4096), + ok(compare_vec4(&cmp[i], out[i].x, out[i].y, out[i].z, out[i].w, 4096), "Vertex %u differs. Got %f %f %f %f.\n", i, out[i].x, out[i].y, out[i].z, out[i].w); } @@ -9657,10 +9657,10 @@ static void test_transform_vertices(void) color = get_surface_color(rt, 128, 147); ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); color = get_surface_color(rt, 132, 147); - todo_wine ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); + ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); color = get_surface_color(rt, 177, 217); - todo_wine ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); + ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); color = get_surface_color(rt, 181, 217); ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); color = get_surface_color(rt, 177, 221); -- 2.7.3 From stefandoesinger at gmx.at Sat Oct 1 12:39:30 2016 From: stefandoesinger at gmx.at (=?UTF-8?q?Stefan=20D=C3=B6singer?=) Date: Sat, 1 Oct 2016 18:39:30 +0100 Subject: [PATCH 4/6] ddraw: Apply legacy clipspace to d3d2. In-Reply-To: <1475343572-5997-1-git-send-email-stefandoesinger@gmx.at> References: <1475343572-5997-1-git-send-email-stefandoesinger@gmx.at> Message-ID: <1475343572-5997-4-git-send-email-stefandoesinger@gmx.at> Signed-off-by: Stefan Dösinger --- dlls/ddraw/device.c | 6 +++--- dlls/ddraw/tests/ddraw2.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index c7a516e..ab94bed 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -3230,7 +3230,7 @@ static HRESULT WINAPI d3d_device2_SetTransform(IDirect3DDevice2 *iface, TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); - return IDirect3DDevice7_SetTransform(&device->IDirect3DDevice7_iface, state, matrix); + return IDirect3DDevice3_SetTransform(&device->IDirect3DDevice3_iface, state, matrix); } /***************************************************************************** @@ -3334,7 +3334,7 @@ static HRESULT WINAPI d3d_device2_GetTransform(IDirect3DDevice2 *iface, TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); - return IDirect3DDevice7_GetTransform(&device->IDirect3DDevice7_iface, state, matrix); + return IDirect3DDevice3_GetTransform(&device->IDirect3DDevice3_iface, state, matrix); } /***************************************************************************** @@ -3441,7 +3441,7 @@ static HRESULT WINAPI d3d_device2_MultiplyTransform(IDirect3DDevice2 *iface, TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); - return IDirect3DDevice7_MultiplyTransform(&device->IDirect3DDevice7_iface, state, matrix); + return IDirect3DDevice3_MultiplyTransform(&device->IDirect3DDevice3_iface, state, matrix); } /***************************************************************************** diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index 65376b3..888dae3 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -10893,7 +10893,7 @@ static void test_transform_vertices(void) {143.0f, 118.0f, 1.0f, 1.0f}, {133.0f, 128.0f, -1.0f, 1.0f}, {133.0f, 128.0f, 0.0f, 1.0f} }; - todo_wine ok(compare_vec4(&cmp[i], out[i].x, out[i].y, out[i].z, out[i].w, 4096), + ok(compare_vec4(&cmp[i], out[i].x, out[i].y, out[i].z, out[i].w, 4096), "Vertex %u differs. Got %f %f %f %f.\n", i, out[i].x, out[i].y, out[i].z, out[i].w); } @@ -10989,14 +10989,14 @@ static void test_transform_vertices(void) color = get_surface_color(rt, 128, 147); ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); color = get_surface_color(rt, 132, 147); - todo_wine ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); + ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); color = get_surface_color(rt, 177, 217); ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); color = get_surface_color(rt, 181, 217); ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); color = get_surface_color(rt, 177, 221); - todo_wine ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); color = get_surface_color(rt, 181, 221); ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); -- 2.7.3 From stefandoesinger at gmx.at Sat Oct 1 12:39:32 2016 From: stefandoesinger at gmx.at (=?UTF-8?q?Stefan=20D=C3=B6singer?=) Date: Sat, 1 Oct 2016 18:39:32 +0100 Subject: [PATCH 6/6] ddraw/tests: Add D3DVIEWPORT2 transform tests. In-Reply-To: <1475343572-5997-1-git-send-email-stefandoesinger@gmx.at> References: <1475343572-5997-1-git-send-email-stefandoesinger@gmx.at> Message-ID: <1475343572-5997-6-git-send-email-stefandoesinger@gmx.at> Signed-off-by: Stefan Dösinger --- dlls/ddraw/tests/ddraw2.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw4.c | 119 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 246 insertions(+) diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index 888dae3..9899566 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -10515,6 +10515,7 @@ static void test_transform_vertices(void) D3DCOLOR color; IDirect3DViewport2 *viewport; IDirect3DMaterial2 *background; + D3DMATERIAL mat; static struct transform_input position_tests[] = { { 0.0f, 0.0f, 0.0f, 0.0f, 1, 2, 3, 4, 5}, @@ -10546,6 +10547,7 @@ static void test_transform_vertices(void) { sizeof(vp_data), 0, 0, 256, 256, 1.0f, 1.0f, 256.0f, 256.0f, 0.0f, 1.0f }; + D3DVIEWPORT2 vp2_data; unsigned int i; DWORD offscreen; static D3DMATRIX mat_scale = @@ -10568,6 +10570,20 @@ static void test_transform_vertices(void) 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, + }, + mat_transform3 = + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 19.2f, 0.0f, 2.0f, + }, + mat_identity = + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, }; static D3DLVERTEX quad[] = { @@ -11000,6 +11016,117 @@ static void test_transform_vertices(void) color = get_surface_color(rt, 181, 221); ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + /* Test D3DVIEWPORT2 behavior. */ + vp2_data.dwSize = sizeof(vp2_data); + vp2_data.dwX = 20; + vp2_data.dwY = 20; + vp2_data.dwWidth = 200; + vp2_data.dwHeight = 400; + vp2_data.dvClipX = -0.5f; + vp2_data.dvClipY = 4.0f; + vp2_data.dvClipWidth = 5.0f; + vp2_data.dvClipHeight = 10.0f; + vp2_data.dvMinZ = 0.0f; + vp2_data.dvMaxZ = 2.0f; + hr = IDirect3DViewport2_SetViewport2(viewport, &vp2_data); + ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x.\n", hr); + transformdata.lpIn = position_tests; + transformdata.lpOut = out; + hr = IDirect3DViewport2_TransformVertices(viewport, ARRAY_SIZE(position_tests), + &transformdata, D3DTRANSFORM_UNCLIPPED, &offscreen); + ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr); + for (i = 0; i < ARRAY_SIZE(position_tests); ++i) + { + static const struct vec4 cmp[] = + { + {120.0f, 140.0f, 0.0f, 1.0f}, {200.0f, 60.0f, 1.0f, 1.0f}, {40.0f, 220.0f, -1.0f, 1.0f}, + {160.0f, 100.0f, 0.5f, 1.0f}, { 80.0f, 180.0f, -0.5f, 1.0f}, {80.0f, 180.0f, 0.0f, 1.0f} + }; + + ok(compare_vec4(&cmp[i], out[i].x, out[i].y, out[i].z, out[i].w, 4096), + "Vertex %u differs. Got %f %f %f %f.\n", i, + out[i].x, out[i].y, out[i].z, out[i].w); + } + + memset(&mat, 0, sizeof(mat)); + mat.dwSize = sizeof(mat); + U1(U(mat).diffuse).r = 0.0f; + U2(U(mat).diffuse).g = 1.0f; + U3(U(mat).diffuse).b = 0.0f; + U4(U(mat).diffuse).a = 0.0f; + hr = IDirect3DMaterial2_SetMaterial(background, &mat); + ok(SUCCEEDED(hr), "Failed to set material data, hr %#x.\n", hr); + hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET); + ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr); + + hr = IDirect3DDevice2_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice2_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DVT_LVERTEX, quad, 4, 0); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice2_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + + color = get_surface_color(rt, 58, 118); + ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 62, 118); + ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 58, 122); + ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 62, 122); + ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); + + color = get_surface_color(rt, 157, 177); + ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 161, 177); + ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 157, 181); + ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 161, 181); + ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color); + + hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &mat_identity); + ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr); + hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_VIEW, &mat_identity); + ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr); + hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, &mat_transform3); + ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr); + + vp2_data.dwX = 0.0; + vp2_data.dwY = 0.0; + vp2_data.dwWidth = 1; + vp2_data.dwHeight = 1; + vp2_data.dvClipX = -12.8f; + vp2_data.dvClipY = 12.8f + mat_transform3._42 / mat_transform3._44; + vp2_data.dvClipWidth = 25.6f; + vp2_data.dvClipHeight = 25.6f; + vp2_data.dvMinZ = 0.0f; + vp2_data.dvMaxZ = 0.5f; + hr = IDirect3DViewport2_SetViewport2(viewport, &vp2_data); + ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x.\n", hr); + transformdata.lpIn = cliptest; + transformdata.dwInSize = sizeof(cliptest[0]); + offscreen = 0xdeadbeef; + hr = IDirect3DViewport2_TransformVertices(viewport, ARRAY_SIZE(cliptest), + &transformdata, D3DTRANSFORM_CLIPPED, &offscreen); + ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr); + ok(!offscreen, "Offscreen is %x.\n", offscreen); + for (i = 0; i < ARRAY_SIZE(cliptest); ++i) + { + static const D3DHVERTEX cmp_h[] = + { + {0, { 25.59f}, { 44.79f}, { 1.0f }}, + {D3DCLIP_RIGHT | D3DCLIP_TOP | D3DCLIP_BACK, { 25.61f}, { 44.81f}, { 1.01f}}, + {0, {-25.59f}, {-6.39f }, { 0.0f }}, + {D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,{-25.61f}, {-6.41f }, {-0.01f}}, + }; + ok(compare_float(U1(cmp_h[i]).hx, U1(out_h[i]).hx, 4096) + && compare_float(U1(cmp_h[i]).hy, U1(out_h[i]).hy, 4096) + && compare_float(U1(cmp_h[i]).hz, U1(out_h[i]).hz, 4096) + && cmp_h[i].dwFlags == out_h[i].dwFlags, + "HVertex %u differs. Got %#x %f %f %f.\n", i, + out_h[i].dwFlags, U1(out_h[i]).hx, U2(out_h[i]).hy, U3(out_h[i]).hz); + } + IDirectDrawSurface_Release(rt); destroy_viewport(device, viewport); IDirect3DMaterial2_Release(background); diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 66301b5..44ef46c 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -11846,6 +11846,7 @@ static void test_transform_vertices(void) { sizeof(vp_data), 0, 0, 256, 256, 1.0f, 1.0f, 256.0f, 256.0f, 0.0f, 1.0f }; + D3DVIEWPORT2 vp2_data; unsigned int i; DWORD offscreen; static D3DMATRIX mat_scale = @@ -11868,6 +11869,20 @@ static void test_transform_vertices(void) 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, + }, + mat_transform3 = + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 19.2f, 0.0f, 2.0f, + }, + mat_identity = + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, }; static struct { @@ -12299,6 +12314,110 @@ static void test_transform_vertices(void) color = get_surface_color(rt, 181, 221); ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color); + /* Test D3DVIEWPORT2 behavior. */ + vp2_data.dwSize = sizeof(vp2_data); + vp2_data.dwX = 20; + vp2_data.dwY = 20; + vp2_data.dwWidth = 200; + vp2_data.dwHeight = 400; + vp2_data.dvClipX = -0.5f; + vp2_data.dvClipY = 4.0f; + vp2_data.dvClipWidth = 5.0f; + vp2_data.dvClipHeight = 10.0f; + vp2_data.dvMinZ = 0.0f; + vp2_data.dvMaxZ = 2.0f; + hr = IDirect3DViewport3_SetViewport2(viewport, &vp2_data); + ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x.\n", hr); + transformdata.lpIn = position_tests; + transformdata.lpOut = out; + hr = IDirect3DViewport3_TransformVertices(viewport, ARRAY_SIZE(position_tests), + &transformdata, D3DTRANSFORM_UNCLIPPED, &offscreen); + ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr); + for (i = 0; i < ARRAY_SIZE(position_tests); ++i) + { + static const struct vec4 cmp[] = + { + {120.0f, 140.0f, 0.0f, 1.0f}, {200.0f, 60.0f, 1.0f, 1.0f}, {40.0f, 220.0f, -1.0f, 1.0f}, + {160.0f, 100.0f, 0.5f, 1.0f}, { 80.0f, 180.0f, -0.5f, 1.0f}, {80.0f, 180.0f, 0.0f, 1.0f} + }; + + ok(compare_vec4(&cmp[i], out[i].x, out[i].y, out[i].z, out[i].w, 4096), + "Vertex %u differs. Got %f %f %f %f.\n", i, + out[i].x, out[i].y, out[i].z, out[i].w); + } + + hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0x0000ff00, 0.0f, 0); + ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr); + + hr = IDirect3DDevice3_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE, + quad, 4, 0); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice3_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + + color = get_surface_color(rt, 58, 118); + ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 62, 118); + ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 58, 122); + ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 62, 122); + ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); + + color = get_surface_color(rt, 157, 177); + ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 161, 177); + ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 157, 181); + ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 161, 181); + ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color); + + hr = IDirect3DDevice3_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &mat_identity); + ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr); + hr = IDirect3DDevice3_SetTransform(device, D3DTRANSFORMSTATE_VIEW, &mat_identity); + ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr); + hr = IDirect3DDevice3_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, &mat_transform3); + ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr); + + vp2_data.dwX = 0.0; + vp2_data.dwY = 0.0; + vp2_data.dwWidth = 1; + vp2_data.dwHeight = 1; + vp2_data.dvClipX = -12.8f; + vp2_data.dvClipY = 12.8f + mat_transform3._42 / mat_transform3._44; + vp2_data.dvClipWidth = 25.6f; + vp2_data.dvClipHeight = 25.6f; + vp2_data.dvMinZ = 0.0f; + vp2_data.dvMaxZ = 0.5f; + hr = IDirect3DViewport3_SetViewport2(viewport, &vp2_data); + ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x.\n", hr); + transformdata.lpIn = cliptest; + transformdata.dwInSize = sizeof(cliptest[0]); + offscreen = 0xdeadbeef; + hr = IDirect3DViewport3_TransformVertices(viewport, ARRAY_SIZE(cliptest), + &transformdata, D3DTRANSFORM_CLIPPED, &offscreen); + ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr); + ok(!offscreen, "Offscreen is %x.\n", offscreen); + for (i = 0; i < ARRAY_SIZE(cliptest); ++i) + { + static const D3DHVERTEX cmp_h[] = + { + {0, { 25.59f}, { 44.79f}, { 1.0f }}, + {D3DCLIP_RIGHT | D3DCLIP_TOP | D3DCLIP_BACK, { 25.61f}, { 44.81f}, { 1.01f}}, + {0, {-25.59f}, {-6.39f }, { 0.0f }}, + {D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,{-25.61f}, {-6.41f }, {-0.01f}}, + }; + ok(compare_float(U1(cmp_h[i]).hx, U1(out_h[i]).hx, 4096) + && compare_float(U1(cmp_h[i]).hy, U1(out_h[i]).hy, 4096) + && compare_float(U1(cmp_h[i]).hz, U1(out_h[i]).hz, 4096) + && cmp_h[i].dwFlags == out_h[i].dwFlags, + "HVertex %u differs. Got %#x %f %f %f.\n", i, + out_h[i].dwFlags, U1(out_h[i]).hx, U2(out_h[i]).hy, U3(out_h[i]).hz); + } + destroy_viewport(device, viewport); IDirectDrawSurface4_Release(rt); refcount = IDirect3DDevice3_Release(device); -- 2.7.3 From stefandoesinger at gmx.at Sat Oct 1 12:39:31 2016 From: stefandoesinger at gmx.at (=?UTF-8?q?Stefan=20D=C3=B6singer?=) Date: Sat, 1 Oct 2016 18:39:31 +0100 Subject: [PATCH 5/6] ddraw: Use the clip space matrix in TransformVertices. In-Reply-To: <1475343572-5997-1-git-send-email-stefandoesinger@gmx.at> References: <1475343572-5997-1-git-send-email-stefandoesinger@gmx.at> Message-ID: <1475343572-5997-5-git-send-email-stefandoesinger@gmx.at> This fixes bug 22317 and most likely 11819, but I only tested the former. Instead of inverting the clip matrix for lpHOut we could do the clip matrix multiplication separately and write lpHOut between the two multiplications, but that has a higher runtime cost. Signed-off-by: Stefan Dösinger --- dlls/ddraw/viewport.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c index 393113e..6364c21 100644 --- a/dlls/ddraw/viewport.c +++ b/dlls/ddraw/viewport.c @@ -395,18 +395,20 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface, { struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface); D3DVIEWPORT vp = viewport->viewports.vp1; - D3DMATRIX view_mat, world_mat, mat; + D3DMATRIX view_mat, world_mat, proj_mat, mat; struct transform_vertices_vertex *in, *out; float x, y, z, w; unsigned int i; D3DHVERTEX *outH; + struct d3d_device *device = viewport->active_device; + BOOL activate = device->current_viewport != viewport; TRACE("iface %p, vertex_count %u, data %p, flags %#x, offscreen %p.\n", iface, dwVertexCount, data, dwFlags, offscreen); /* Tests on windows show that Windows crashes when this occurs, * so don't return the (intuitive) return value - if (!viewport->active_device) + if (!device) { WARN("No device active, returning D3DERR_VIEWPORTHASNODEVICE\n"); return D3DERR_VIEWPORTHASNODEVICE; @@ -424,14 +426,18 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface, return DDERR_INVALIDPARAMS; } - wined3d_mutex_lock(); - wined3d_device_get_transform(viewport->active_device->wined3d_device, + if (activate) + viewport_activate(viewport, TRUE); + + wined3d_device_get_transform(device->wined3d_device, D3DTRANSFORMSTATE_VIEW, (struct wined3d_matrix *)&view_mat); - wined3d_device_get_transform(viewport->active_device->wined3d_device, + wined3d_device_get_transform(device->wined3d_device, WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix *)&world_mat); + wined3d_device_get_transform(device->wined3d_device, + WINED3D_TS_PROJECTION, (struct wined3d_matrix *)&proj_mat); multiply_matrix(&mat, &view_mat, &world_mat); - multiply_matrix(&mat, &viewport->active_device->legacy_projection, &mat); + multiply_matrix(&mat, &proj_mat, &mat); /* The pointer is not tested against NULL on Windows. */ if (dwFlags & D3DTRANSFORM_CLIPPED) @@ -453,22 +459,23 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface, if(dwFlags & D3DTRANSFORM_CLIPPED) { /* If clipping is enabled, Windows assumes that outH is - * a valid pointer - */ - outH[i].u1.hx = x; outH[i].u2.hy = y; outH[i].u3.hz = z; + * a valid pointer. */ + outH[i].u1.hx = (x - device->legacy_clipspace._41 * w) / device->legacy_clipspace._11; + outH[i].u2.hy = (y - device->legacy_clipspace._42 * w) / device->legacy_clipspace._22; + outH[i].u3.hz = (z - device->legacy_clipspace._43 * w) / device->legacy_clipspace._33; outH[i].dwFlags = 0; - if(x * vp.dvScaleX > ((float) vp.dwWidth * 0.5)) + if (x > w) outH[i].dwFlags |= D3DCLIP_RIGHT; - if(x * vp.dvScaleX <= -((float) vp.dwWidth) * 0.5) + if (x < -w) outH[i].dwFlags |= D3DCLIP_LEFT; - if(y * vp.dvScaleY > ((float) vp.dwHeight * 0.5)) + if (y > w) outH[i].dwFlags |= D3DCLIP_TOP; - if(y * vp.dvScaleY <= -((float) vp.dwHeight) * 0.5) + if (y < -w) outH[i].dwFlags |= D3DCLIP_BOTTOM; - if(z < 0.0) + if (z < 0.0f) outH[i].dwFlags |= D3DCLIP_FRONT; - if(z > 1.0) + if (z > w) outH[i].dwFlags |= D3DCLIP_BACK; *offscreen &= outH[i].dwFlags; @@ -491,13 +498,16 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface, w = 1 / w; x *= w; y *= w; z *= w; - out->x = vp.dwWidth / 2 + vp.dwX + x * vp.dvScaleX; - out->y = vp.dwHeight / 2 + vp.dwY - y * vp.dvScaleY; + out->x = (x + 1.0f) * vp.dwWidth * 0.5 + vp.dwX; + out->y = (-y + 1.0f) * vp.dwHeight * 0.5 + vp.dwY; out->z = z; out->w = w; out->payload = in->payload; } + if (activate && device->current_viewport) + viewport_activate(device->current_viewport, TRUE); + wined3d_mutex_unlock(); TRACE("All done\n"); -- 2.7.3 From kimmo.myllyvirta at gmail.com Sun Oct 2 01:39:13 2016 From: kimmo.myllyvirta at gmail.com (Kimmo Myllyvirta) Date: Sun, 2 Oct 2016 09:39:13 +0300 Subject: [PATCH] d3d11: Add stub implementation for deferred context. Message-ID: <57F0AB91.3080604@gmail.com> For bug 39180. -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-d3d11-Add-stub-implementation-for-deferred-context.patch Type: text/x-patch Size: 50252 bytes Desc: not available URL: From gerald at pfeifer.com Sun Oct 2 00:40:36 2016 From: gerald at pfeifer.com (Gerald Pfeifer) Date: Sun, 2 Oct 2016 07:40:36 +0200 (CEST) Subject: winedbg: Extend buffer in packet_query_monitor_process to avoid avoid overrun/truncation. Message-ID: PROCESSENTRY32 declares szExeFile as char[MAX_PATH], yet buffer in packet_query_monitor_process is declared as char[128]. This means snprintf(buffer, sizeof(buffer), "%c%08x %-8d %08x '%s'\n", deco, entry.th32ProcessID, entry.cntThreads, entry.th32ParentProcessID, entry.szExeFile); there may be running over (well, not really, since it's snprintf, not plain sprintf, but still). GCC 7 is going to warn about this, by the way. Gerald Signed-off-by: Gerald Pfeifer --- programs/winedbg/gdbproxy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c index 7f0a8c9..f94fef5 100644 --- a/programs/winedbg/gdbproxy.c +++ b/programs/winedbg/gdbproxy.c @@ -1710,7 +1710,7 @@ static void packet_query_monitor_wnd(struct gdb_context* gdbctx, int len, const static void packet_query_monitor_process(struct gdb_context* gdbctx, int len, const char* str) { HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - char buffer[128]; + char buffer[31+MAX_PATH]; char deco; PROCESSENTRY32 entry; BOOL ok; -- 2.9.2 From gerald at pfeifer.com Sun Oct 2 05:15:40 2016 From: gerald at pfeifer.com (Gerald Pfeifer) Date: Sun, 2 Oct 2016 12:15:40 +0200 (CEST) Subject: wininet: Increase buffer in _test_status_code to avoid potential potential overflow. Message-ID: In _test_status_code exbuf is char[10], but we then use this in sprintf(exbuf, "%u", excode) which can, in principle, print 10 digits plus the final \0, thus 11 chars. I opted to make the buffer 12 chars instead of only 11, for simplicity, to technically also be large enough for signed values, and since with natural variable alignment this doesn't actually cost us anything. This is another case that GCC 7 is going to warn about. There aren't many more left in all of Wine, though, which speaks for the quality of the codebase. ;-) Gerald Signed-off-by: Gerald Pfeifer --- dlls/wininet/tests/http.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c index fc68fe1..f2fe25c 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c @@ -200,7 +200,7 @@ static BOOL proxy_active(void) static void _test_status_code(unsigned line, HINTERNET req, DWORD excode, BOOL is_todo) { DWORD code, size, index; - char exbuf[10], bufa[10]; + char exbuf[12], bufa[10]; WCHAR bufw[10]; BOOL res; -- 2.9.2 From nerv at dawncrow.de Sun Oct 2 07:48:55 2016 From: nerv at dawncrow.de (=?UTF-8?Q?Andr=c3=a9_Hentschel?=) Date: Sun, 2 Oct 2016 14:48:55 +0200 Subject: shell32/tests: Mark win10 failure as broken Message-ID: <415d98dd-4060-2c34-3425-e861b3dd3ca2@dawncrow.de> Signed-off-by: André Hentschel --- dlls/shell32/tests/shlfolder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-shell32-tests-Mark-win10-failure-as-broken.txt Type: text/x-patch Size: 666 bytes Desc: not available URL: From sagawa.aki at gmail.com Sun Oct 2 10:06:55 2016 From: sagawa.aki at gmail.com (Akihiro Sagawa) Date: Mon, 03 Oct 2016 00:06:55 +0900 Subject: [1/2] [v2] kernel32: Implement LCMAP_FULLWIDTH. Message-ID: <20161003000650.77FD.375B48EC@gmail.com> v2: Avoid allocating buffer memory. (includes adaptation map_to_fullwidth function, reorder LCMAP_HIRAGANA and LCMAP_KATAKANA position) Simplify mapping tables for symbols and Hangul variants. Signed-off-by: Akihiro Sagawa --- dlls/kernel32/locale.c | 195 +++++++++++++++++++++++++++++++++++++------ dlls/kernel32/tests/locale.c | 12 ++- 2 files changed, 179 insertions(+), 28 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-v2-kernel32-Implement-LCMAP_FULLWIDTH.patch Type: text/x-patch Size: 10712 bytes Desc: not available URL: From sagawa.aki at gmail.com Sun Oct 2 10:06:57 2016 From: sagawa.aki at gmail.com (Akihiro Sagawa) Date: Mon, 03 Oct 2016 00:06:57 +0900 Subject: [2/2] [v2] kernel32: Implement LCMAP_HALFWIDTH. Message-ID: <20161003000650.77FE.375B48EC@gmail.com> v2: Avoid allocating buffer while mapping. (includes adaptation map_to_fullwidth function) Signed-off-by: Akihiro Sagawa --- dlls/kernel32/locale.c | 121 ++++++++++++++++++++++++++++++++++++++++++- dlls/kernel32/tests/locale.c | 10 ++-- 2 files changed, 126 insertions(+), 5 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-v2-kernel32-Implement-LCMAP_HALFWIDTH.patch Type: text/x-patch Size: 7239 bytes Desc: not available URL: From aric at codeweavers.com Sun Oct 2 17:09:11 2016 From: aric at codeweavers.com (Aric Stewart) Date: Sun, 2 Oct 2016 17:09:11 -0500 Subject: [PATCH v8] winebus.sys: Watch for hid raw device addition and removal Message-ID: <895e1cdc-b707-f6c7-3acf-f4494ce63480@codeweavers.com> v2: Correct poll timeout Style changes v3: vtable style instead of a callback v4: Suggestions from Sebastian Lackner v5: Fixing handling of other native in the compare function v6: Tweaks suggested by Sebastian Lackner v7: Further suggestions from Sebastian Lackner v8: Move initial set into thread as per Alexandre Julliard's suggestion Includes an implementation of a common bus_remove_hid_device Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 13 ++++- dlls/winebus.sys/bus_udev.c | 115 ++++++++++++++++++++++++++++++++++++++++++-- dlls/winebus.sys/main.c | 66 ++++++++++++++++++++----- 3 files changed, 177 insertions(+), 17 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: v8-0001-winebus.sys-Watch-for-hid-raw-device-addition-and-r.txt Type: text/x-patch Size: 11748 bytes Desc: not available URL: From jkucia at codeweavers.com Sun Oct 2 17:38:36 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 3 Oct 2016 00:38:36 +0200 Subject: [PATCH 1/7] wined3d: Use MAX_TEXTURES instead of magic number. Message-ID: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/arb_program_shader.c | 4 ++-- dlls/wined3d/ati_fragment_shader.c | 2 +- dlls/wined3d/glsl_shader.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index f809e4a..f8ecb80 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -5934,8 +5934,8 @@ static void arbfp_get_caps(const struct wined3d_gl_info *gl_info, struct fragmen /* TODO: Implement WINED3DTEXOPCAPS_PREMODULATE */ - caps->MaxTextureBlendStages = 8; - caps->MaxSimultaneousTextures = min(gl_info->limits.fragment_samplers, 8); + caps->MaxTextureBlendStages = MAX_TEXTURES; + caps->MaxSimultaneousTextures = min(gl_info->limits.fragment_samplers, MAX_TEXTURES); } static DWORD arbfp_get_emul_mask(const struct wined3d_gl_info *gl_info) diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index cd32009..7a04f76 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -1307,7 +1307,7 @@ static void atifs_get_caps(const struct wined3d_gl_info *gl_info, struct fragmen * The proper fix for this is not to use GL_ATI_fragment_shader on cards newer than the * r200 series and use an ARB or GLSL shader instead */ - caps->MaxTextureBlendStages = 8; + caps->MaxTextureBlendStages = MAX_TEXTURES; caps->MaxSimultaneousTextures = 6; } diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index b0f3224..55cbdcf 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -9433,8 +9433,8 @@ static void glsl_fragment_pipe_get_caps(const struct wined3d_gl_info *gl_info, s | WINED3DTEXOPCAPS_LERP | WINED3DTEXOPCAPS_BUMPENVMAP | WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE; - caps->MaxTextureBlendStages = 8; - caps->MaxSimultaneousTextures = min(gl_info->limits.fragment_samplers, 8); + caps->MaxTextureBlendStages = MAX_TEXTURES; + caps->MaxSimultaneousTextures = min(gl_info->limits.fragment_samplers, MAX_TEXTURES); } static DWORD glsl_fragment_pipe_get_emul_mask(const struct wined3d_gl_info *gl_info) -- 2.7.3 From jkucia at codeweavers.com Sun Oct 2 17:38:37 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 3 Oct 2016 00:38:37 +0200 Subject: [PATCH 2/7] wined3d: Do not create separate dummy texture for each texture image unit. In-Reply-To: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> References: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1475447922-2579-2-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/context.c | 41 +++++------ dlls/wined3d/device.c | 150 ++++++++++++++++++----------------------- dlls/wined3d/wined3d_private.h | 15 +++-- 3 files changed, 90 insertions(+), 116 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index b5a4589..a362247 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1511,7 +1511,7 @@ static int context_choose_pixel_format(const struct wined3d_device *device, HDC } /* Context activation is done by the caller. */ -static void bind_dummy_textures(const struct wined3d_device *device, const struct wined3d_context *context) +void context_bind_dummy_textures(const struct wined3d_device *device, const struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int i, count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers); @@ -1521,32 +1521,21 @@ static void bind_dummy_textures(const struct wined3d_device *device, const struc GL_EXTCALL(glActiveTexture(GL_TEXTURE0 + i)); checkGLcall("glActiveTexture"); - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_texture_2d[i]); - checkGLcall("glBindTexture"); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_textures.tex_2d); if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) - { - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_texture_rect[i]); - checkGLcall("glBindTexture"); - } + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_textures.tex_rect); if (gl_info->supported[EXT_TEXTURE3D]) - { - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[i]); - checkGLcall("glBindTexture"); - } + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_textures.tex_3d); if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_texture_cube[i]); - checkGLcall("glBindTexture"); - } + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_textures.tex_cube); if (gl_info->supported[EXT_TEXTURE_ARRAY]) - { - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, device->dummy_texture_2d_array[i]); - checkGLcall("glBindTexture"); - } + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, device->dummy_textures.tex_2d_array); + + checkGLcall("Bind dummy textures"); } } @@ -1993,8 +1982,8 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, /* If this happens to be the first context for the device, dummy textures * are not created yet. In that case, they will be created (and bound) by * create_dummy_textures right after this context is initialized. */ - if (device->dummy_texture_2d[0]) - bind_dummy_textures(device, ret); + if (device->dummy_textures.tex_2d) + context_bind_dummy_textures(device, ret); TRACE("Created context %p.\n", ret); @@ -2393,23 +2382,23 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint /* nothing to do */ break; case GL_TEXTURE_2D: - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_texture_2d[unit]); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_textures.tex_2d); checkGLcall("glBindTexture"); break; case GL_TEXTURE_2D_ARRAY: - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, device->dummy_texture_2d_array[unit]); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, device->dummy_textures.tex_2d_array); checkGLcall("glBindTexture"); break; case GL_TEXTURE_RECTANGLE_ARB: - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_texture_rect[unit]); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_textures.tex_rect); checkGLcall("glBindTexture"); break; case GL_TEXTURE_CUBE_MAP: - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_texture_cube[unit]); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_textures.tex_cube); checkGLcall("glBindTexture"); break; case GL_TEXTURE_3D: - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[unit]); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_textures.tex_3d); checkGLcall("glBindTexture"); break; default: diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 2db1af8..b8ac88a 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -684,7 +684,7 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_ { const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - unsigned int i, j, count; + unsigned int i; DWORD color; if (d3d_info->wined3d_creation_flags & WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR) @@ -696,121 +696,101 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_ * OpenGL will only allow that when a valid texture is bound. * We emulate this by creating dummy textures and binding them * to each texture stage when the currently set D3D texture is NULL. */ - count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers); - for (i = 0; i < count; ++i) + context_active_texture(context, gl_info, 0); + + gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_2d); + checkGLcall("glGenTextures"); + TRACE("Dummy 2D texture given name %u.\n", device->dummy_textures.tex_2d); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_textures.tex_2d); + checkGLcall("glBindTexture"); + + gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color); + checkGLcall("glTexImage2D"); + + if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) { - /* Make appropriate texture active */ - context_active_texture(context, gl_info, i); - - gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_texture_2d[i]); + gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_rect); checkGLcall("glGenTextures"); - TRACE("Dummy 2D texture %u given name %u.\n", i, device->dummy_texture_2d[i]); + TRACE("Dummy rectangle texture given name %u.\n", device->dummy_textures.tex_rect); - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_texture_2d[i]); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_textures.tex_rect); checkGLcall("glBindTexture"); - gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, + gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color); checkGLcall("glTexImage2D"); + } - if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) + if (gl_info->supported[EXT_TEXTURE3D]) + { + gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_3d); + checkGLcall("glGenTextures"); + TRACE("Dummy 3D texture given name %u.\n", device->dummy_textures.tex_3d); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_textures.tex_3d); + checkGLcall("glBindTexture"); + + GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color)); + checkGLcall("glTexImage3D"); + } + + if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + { + gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_cube); + checkGLcall("glGenTextures"); + TRACE("Dummy cube texture given name %u.\n", device->dummy_textures.tex_cube); + + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_textures.tex_cube); + checkGLcall("glBindTexture"); + + for (i = GL_TEXTURE_CUBE_MAP_POSITIVE_X; i <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++i) { - gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_texture_rect[i]); - checkGLcall("glGenTextures"); - TRACE("Dummy rectangle texture %u given name %u.\n", i, device->dummy_texture_rect[i]); - - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_texture_rect[i]); - checkGLcall("glBindTexture"); - - gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, 1, 1, 0, + gl_info->gl_ops.gl.p_glTexImage2D(i, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color); checkGLcall("glTexImage2D"); } + } - if (gl_info->supported[EXT_TEXTURE3D]) - { - gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_texture_3d[i]); - checkGLcall("glGenTextures"); - TRACE("Dummy 3D texture %u given name %u.\n", i, device->dummy_texture_3d[i]); - - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[i]); - checkGLcall("glBindTexture"); - - GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color)); - checkGLcall("glTexImage3D"); - } - - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_texture_cube[i]); - checkGLcall("glGenTextures"); - TRACE("Dummy cube texture %u given name %u.\n", i, device->dummy_texture_cube[i]); - - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_texture_cube[i]); - checkGLcall("glBindTexture"); - - for (j = GL_TEXTURE_CUBE_MAP_POSITIVE_X; j <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++j) - { - gl_info->gl_ops.gl.p_glTexImage2D(j, 0, GL_RGBA8, 1, 1, 0, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color); - checkGLcall("glTexImage2D"); - } - } - - if (gl_info->supported[EXT_TEXTURE_ARRAY]) - { - gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_texture_2d_array[i]); - checkGLcall("glGenTextures"); - TRACE("Dummy 2D array texture %u given name %u.\n", i, device->dummy_texture_2d_array[i]); + if (gl_info->supported[EXT_TEXTURE_ARRAY]) + { + gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_textures.tex_2d_array); + checkGLcall("glGenTextures"); + TRACE("Dummy 2D array texture given name %u.\n", device->dummy_textures.tex_2d_array); - gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, device->dummy_texture_2d_array[i]); - checkGLcall("glBindTexture"); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, device->dummy_textures.tex_2d_array); + checkGLcall("glBindTexture"); - GL_EXTCALL(glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 1, 0, + GL_EXTCALL(glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color)); - checkGLcall("glTexImage3D"); - } + checkGLcall("glTexImage3D"); } + + context_bind_dummy_textures(device, context); } /* Context activation is done by the caller. */ static void destroy_dummy_textures(struct wined3d_device *device, const struct wined3d_gl_info *gl_info) { - unsigned int count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers); - if (gl_info->supported[EXT_TEXTURE_ARRAY]) - { - gl_info->gl_ops.gl.p_glDeleteTextures(count, device->dummy_texture_2d_array); - checkGLcall("glDeleteTextures(count, device->dummy_texture_2d_array)"); - } + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_2d_array); if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - gl_info->gl_ops.gl.p_glDeleteTextures(count, device->dummy_texture_cube); - checkGLcall("glDeleteTextures(count, device->dummy_texture_cube)"); - } + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_cube); if (gl_info->supported[EXT_TEXTURE3D]) - { - gl_info->gl_ops.gl.p_glDeleteTextures(count, device->dummy_texture_3d); - checkGLcall("glDeleteTextures(count, device->dummy_texture_3d)"); - } + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_3d); if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) - { - gl_info->gl_ops.gl.p_glDeleteTextures(count, device->dummy_texture_rect); - checkGLcall("glDeleteTextures(count, device->dummy_texture_rect)"); - } + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_rect); - gl_info->gl_ops.gl.p_glDeleteTextures(count, device->dummy_texture_2d); - checkGLcall("glDeleteTextures(count, device->dummy_texture_2d)"); + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_2d); - memset(device->dummy_texture_2d_array, 0, count * sizeof(*device->dummy_texture_2d_array)); - memset(device->dummy_texture_cube, 0, count * sizeof(*device->dummy_texture_cube)); - memset(device->dummy_texture_3d, 0, count * sizeof(*device->dummy_texture_3d)); - memset(device->dummy_texture_rect, 0, count * sizeof(*device->dummy_texture_rect)); - memset(device->dummy_texture_2d, 0, count * sizeof(*device->dummy_texture_2d)); + checkGLcall("Delete dummy textures"); + + memset(&device->dummy_textures, 0, sizeof(device->dummy_textures)); } /* Context activation is done by the caller. */ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 9e8fde3..a968bda 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1720,6 +1720,8 @@ void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) DECLSPEC_HIDDEN; void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, unsigned int unit) DECLSPEC_HIDDEN; +void context_bind_dummy_textures(const struct wined3d_device *device, + const struct wined3d_context *context) DECLSPEC_HIDDEN; void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint name) DECLSPEC_HIDDEN; void context_check_fbo_status(const struct wined3d_context *context, GLenum target) DECLSPEC_HIDDEN; struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, struct wined3d_texture *target, @@ -2484,11 +2486,14 @@ struct wined3d_device struct wined3d_texture *logo_texture; /* Textures for when no other textures are mapped */ - GLuint dummy_texture_2d[MAX_COMBINED_SAMPLERS]; - GLuint dummy_texture_rect[MAX_COMBINED_SAMPLERS]; - GLuint dummy_texture_3d[MAX_COMBINED_SAMPLERS]; - GLuint dummy_texture_cube[MAX_COMBINED_SAMPLERS]; - GLuint dummy_texture_2d_array[MAX_COMBINED_SAMPLERS]; + struct + { + GLuint tex_2d; + GLuint tex_rect; + GLuint tex_3d; + GLuint tex_cube; + GLuint tex_2d_array; + } dummy_textures; /* Default sampler used to emulate the direct resource access without using wined3d_sampler */ GLuint default_sampler; -- 2.7.3 From jkucia at codeweavers.com Sun Oct 2 17:38:38 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 3 Oct 2016 00:38:38 +0200 Subject: [PATCH 3/7] wined3d: Bind dummy textures to all texture image units. In-Reply-To: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> References: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1475447922-2579-3-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/context.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index a362247..e09c6fd 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1514,9 +1514,9 @@ static int context_choose_pixel_format(const struct wined3d_device *device, HDC void context_bind_dummy_textures(const struct wined3d_device *device, const struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int i, count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers); + unsigned int i; - for (i = 0; i < count; ++i) + for (i = 0; i < gl_info->limits.combined_samplers; ++i) { GL_EXTCALL(glActiveTexture(GL_TEXTURE0 + i)); checkGLcall("glActiveTexture"); -- 2.7.3 From jkucia at codeweavers.com Sun Oct 2 17:38:39 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 3 Oct 2016 00:38:39 +0200 Subject: [PATCH 4/7] wined3d: Avoid using destroyed context. In-Reply-To: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> References: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1475447922-2579-4-git-send-email-jkucia@codeweavers.com> The swapchain can be destroyed by state_unbind_resources() if the only reference to a swapchain is kept by a shader resource view. This happens in d3d10core and d3d11 tests when a device is destroyed in test_swapchain_flip(). Signed-off-by: Józef Kucia --- This snip from a "WINEDEBUG=+d3d,warn+heap" log shows the problem: trace:d3d:context_enter Entering context 0x17c4c8, level 2. trace:d3d:context_release Releasing context 0x17c4c8, level 2. trace:d3d:context_destroy Destroying ctx 0x17c4c8 trace:d3d:context_destroy_fbo_entry Destroy FBO 4. trace:d3d:context_destroy_fbo_entry Destroy FBO 1. trace:d3d:context_destroy_fbo_entry Destroy FBO 3. trace:d3d:context_destroy_fbo_entry Destroy FBO 5. trace:d3d:context_destroy_fbo_entry Destroy FBO 2. trace:d3d:device_context_remove Removing context 0x17c4c8. trace:d3d:context_acquire device 0x150bf0, target (nil). trace:d3d:context_acquire Rendering onscreen. trace:d3d:context_enter Entering context 0x16e7d8, level 1. ... trace:d3d:context_release Releasing context 0x17c4c8, level 4277075694. warn:d3d:context_release Context 0x17c4c8 is not the current context. 4277075694 is 0xfeeefeee --- dlls/wined3d/device.c | 21 ++++++++++++--------- dlls/wined3d/stateblock.c | 25 ++++++++++++++++++------- dlls/wined3d/wined3d_private.h | 1 + 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index b8ac88a..63889af 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1159,14 +1159,7 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) if (device->cursor_texture) wined3d_texture_decref(device->cursor_texture); - state_unbind_resources(&device->state); - - /* Unload resources */ - LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) - { - TRACE("Unloading resource %p.\n", resource); - wined3d_cs_emit_unload_resource(device->cs, resource); - } + state_unbind_shaders(&device->state); wine_rb_clear(&device->samplers, device_free_sampler, NULL); @@ -1186,11 +1179,20 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) destroy_default_samplers(device); /* Release the context again as soon as possible. In particular, - * releasing the render target views below may release the last reference + * releasing the resource views below may release the last reference * to the swapchain associated with this context, which in turn will * destroy the context. */ context_release(context); + state_unbind_resources(&device->state); + + /* Unload resources */ + LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) + { + TRACE("Unloading resource %p.\n", resource); + wined3d_cs_emit_unload_resource(device->cs, resource); + } + /* Release the buffers (with sanity checks)*/ if (device->onscreen_depth_stencil) { @@ -4659,6 +4661,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, device->cursor_texture = NULL; } state_unbind_resources(&device->state); + state_unbind_shaders(&device->state); } if (device->fb.render_targets) diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 2fbfa2c..122dc0e 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -429,7 +429,6 @@ void state_unbind_resources(struct wined3d_state *state) struct wined3d_sampler *sampler; struct wined3d_texture *texture; struct wined3d_buffer *buffer; - struct wined3d_shader *shader; unsigned int i, j; if ((decl = state->vertex_declaration)) @@ -473,12 +472,6 @@ void state_unbind_resources(struct wined3d_state *state) for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) { - if ((shader = state->shader[i])) - { - state->shader[i] = NULL; - wined3d_shader_decref(shader); - } - for (j = 0; j < MAX_CONSTANT_BUFFERS; ++j) { if ((buffer = state->cb[i][j])) @@ -508,12 +501,30 @@ void state_unbind_resources(struct wined3d_state *state) } } +void state_unbind_shaders(struct wined3d_state *state) +{ + struct wined3d_shader *shader; + unsigned int i; + + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) + { + if ((shader = state->shader[i])) + { + state->shader[i] = NULL; + wined3d_shader_decref(shader); + } + } +} + void state_cleanup(struct wined3d_state *state) { unsigned int counter; if (!(state->flags & WINED3D_STATE_NO_REF)) + { state_unbind_resources(state); + state_unbind_shaders(state); + } for (counter = 0; counter < MAX_ACTIVE_LIGHTS; ++counter) { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index a968bda..226d55f 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3017,6 +3017,7 @@ void state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN; void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; +void state_unbind_shaders(struct wined3d_state *state) DECLSPEC_HIDDEN; enum wined3d_push_constants { -- 2.7.3 From jkucia at codeweavers.com Sun Oct 2 17:38:40 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 3 Oct 2016 00:38:40 +0200 Subject: [PATCH 5/7] wined3d: Pass context to create_default_samplers(). In-Reply-To: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> References: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1475447922-2579-5-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/device.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 63889af..8a4b62d 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -794,9 +794,9 @@ static void destroy_dummy_textures(struct wined3d_device *device, const struct w } /* Context activation is done by the caller. */ -static void create_default_samplers(struct wined3d_device *device) +static void create_default_samplers(struct wined3d_device *device, struct wined3d_context *context) { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + const struct wined3d_gl_info *gl_info = context->gl_info; if (gl_info->supported[ARB_SAMPLER_OBJECTS]) { @@ -1058,7 +1058,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, context = context_acquire(device, NULL); create_dummy_textures(device, context); - create_default_samplers(device); + create_default_samplers(device, context); device->contexts[0]->last_was_rhw = 0; @@ -4622,7 +4622,7 @@ static HRESULT create_primary_opengl_context(struct wined3d_device *device, stru swapchain->context[0] = context; swapchain->num_contexts = 1; create_dummy_textures(device, context); - create_default_samplers(device); + create_default_samplers(device, context); context_release(context); return WINED3D_OK; -- 2.7.3 From jkucia at codeweavers.com Sun Oct 2 17:38:41 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 3 Oct 2016 00:38:41 +0200 Subject: [PATCH 6/7] wined3d: Pass context to destroy_default_samplers(). In-Reply-To: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> References: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1475447922-2579-6-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/device.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 8a4b62d..862344a 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -827,9 +827,9 @@ static void create_default_samplers(struct wined3d_device *device, struct wined3 } /* Context activation is done by the caller. */ -static void destroy_default_samplers(struct wined3d_device *device) +static void destroy_default_samplers(struct wined3d_device *device, struct wined3d_context *context) { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + const struct wined3d_gl_info *gl_info = context->gl_info; if (gl_info->supported[ARB_SAMPLER_OBJECTS]) { @@ -1176,7 +1176,7 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) device->blitter->free_private(device); device->shader_backend->shader_free_private(device); destroy_dummy_textures(device, gl_info); - destroy_default_samplers(device); + destroy_default_samplers(device, context); /* Release the context again as soon as possible. In particular, * releasing the resource views below may release the last reference @@ -4566,7 +4566,7 @@ static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d device->blitter->free_private(device); device->shader_backend->shader_free_private(device); destroy_dummy_textures(device, gl_info); - destroy_default_samplers(device); + destroy_default_samplers(device, context); context_release(context); -- 2.7.3 From jkucia at codeweavers.com Sun Oct 2 17:38:42 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 3 Oct 2016 00:38:42 +0200 Subject: [PATCH 7/7] wined3d: Pass context to destroy_dummy_textures(). In-Reply-To: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> References: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1475447922-2579-7-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/device.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 862344a..6272ac5 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -772,8 +772,10 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_ } /* Context activation is done by the caller. */ -static void destroy_dummy_textures(struct wined3d_device *device, const struct wined3d_gl_info *gl_info) +static void destroy_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; + if (gl_info->supported[EXT_TEXTURE_ARRAY]) gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_2d_array); @@ -1175,7 +1177,7 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) /* Destroy the shader backend. Note that this has to happen after all shaders are destroyed. */ device->blitter->free_private(device); device->shader_backend->shader_free_private(device); - destroy_dummy_textures(device, gl_info); + destroy_dummy_textures(device, context); destroy_default_samplers(device, context); /* Release the context again as soon as possible. In particular, @@ -4565,7 +4567,7 @@ static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d device->blitter->free_private(device); device->shader_backend->shader_free_private(device); - destroy_dummy_textures(device, gl_info); + destroy_dummy_textures(device, context); destroy_default_samplers(device, context); context_release(context); -- 2.7.3 From alexhenrie24 at gmail.com Mon Oct 3 01:14:37 2016 From: alexhenrie24 at gmail.com (Alex Henrie) Date: Mon, 3 Oct 2016 00:14:37 -0600 Subject: [PATCH] msinfo32: Display an About dialog when the program is run. Message-ID: <20161003061437.31671-1-alexhenrie24@gmail.com> Cc: Austin English Fixes https://bugs.winehq.org/show_bug.cgi?id=41430 An About dialog displays the most important piece of information (the Wine version), and we were going to have to add one to this program eventually anyway. msinfo32 does not take any command line arguments, so I changed WINE_FIXME to WINE_TRACE. --- programs/msinfo32/Makefile.in | 3 +++ programs/msinfo32/main.c | 15 ++++++++++++--- programs/msinfo32/msinfo32.rc | 24 ++++++++++++++++++++++++ programs/msinfo32/resource.h | 19 +++++++++++++++++++ 4 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 programs/msinfo32/msinfo32.rc create mode 100644 programs/msinfo32/resource.h diff --git a/programs/msinfo32/Makefile.in b/programs/msinfo32/Makefile.in index e958c27..d752c91 100644 --- a/programs/msinfo32/Makefile.in +++ b/programs/msinfo32/Makefile.in @@ -1,5 +1,8 @@ MODULE = msinfo32.exe APPMODE = -mwindows -municode +IMPORTS = shell32 user32 C_SRCS = \ main.c + +RC_SRCS = msinfo32.rc diff --git a/programs/msinfo32/main.c b/programs/msinfo32/main.c index 77bb927..f63095c 100644 --- a/programs/msinfo32/main.c +++ b/programs/msinfo32/main.c @@ -16,18 +16,27 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include + +#include "resource.h" +#include "shellapi.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(msinfo); int wmain(int argc, WCHAR *argv[]) { + static const WCHAR wineSystemInfoW[] = + {'W','i','n','e',' ','S','y','s','t','e','m',' ','I','n','f','o','r','m','a','t','i','o','n',0}; + WCHAR systemInfo[64]; int i; - WINE_FIXME("stub:"); for (i = 0; i < argc; i++) - WINE_FIXME(" %s", wine_dbgstr_w(argv[i])); - WINE_FIXME("\n"); + WINE_TRACE(" %s", wine_dbgstr_w(argv[i])); + WINE_TRACE("\n"); + + LoadStringW(GetModuleHandleW(NULL), STRING_SYSTEM_INFO, systemInfo, sizeof(systemInfo)/sizeof(WCHAR)); + ShellAboutW(NULL, systemInfo, wineSystemInfoW, NULL); return 0; } diff --git a/programs/msinfo32/msinfo32.rc b/programs/msinfo32/msinfo32.rc new file mode 100644 index 0000000..ce4ab62 --- /dev/null +++ b/programs/msinfo32/msinfo32.rc @@ -0,0 +1,24 @@ +/* + * Copyright 2016 Alex Henrie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "resource.h" + +STRINGTABLE +{ + STRING_SYSTEM_INFO, "System Information" +} diff --git a/programs/msinfo32/resource.h b/programs/msinfo32/resource.h new file mode 100644 index 0000000..953a00d --- /dev/null +++ b/programs/msinfo32/resource.h @@ -0,0 +1,19 @@ +/* + * Copyright 2016 Alex Henrie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define STRING_SYSTEM_INFO 0x170 -- 2.10.0 From alexhenrie24 at gmail.com Mon Oct 3 01:25:14 2016 From: alexhenrie24 at gmail.com (Alex Henrie) Date: Mon, 3 Oct 2016 00:25:14 -0600 Subject: [PATCH] msinfo32: Display an About dialog when the program is run. In-Reply-To: <20161003061437.31671-1-alexhenrie24@gmail.com> References: <20161003061437.31671-1-alexhenrie24@gmail.com> Message-ID: Signed-off-by: Alex Henrie From sebastian at fds-team.de Mon Oct 3 06:24:44 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Mon, 3 Oct 2016 13:24:44 +0200 Subject: [1/3] winebus.sys: Spawn a device loop thread and add synchronization. Message-ID: <60d6665a-7f1a-962f-f23b-831f555062d2@fds-team.de> Signed-off-by: Sebastian Lackner --- Alexandres remark that we should probably build the initial deviceset from the monitor thread is valid, and I have also thought about that in the past. Nevertheless, I think it is a good idea to have some synchronization at least, so that we do not proceed with the execution until we are done with the initialization. dlls/winebus.sys/bus_udev.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 1525861..1f6df6f 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -164,8 +164,21 @@ static void build_initial_deviceset(void) udev_enumerate_unref(enumerate); } +static DWORD CALLBACK deviceloop_thread(void *args) +{ + HANDLE init_done = args; + + build_initial_deviceset(); + SetEvent(init_done); + + return 0; +} + NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path) { + HANDLE events[2]; + DWORD result; + TRACE("(%p, %s)\n", driver, debugstr_w(registry_path->Buffer)); if (!(udev_context = udev_new())) @@ -177,8 +190,29 @@ NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry udev_driver_obj = driver; driver->MajorFunction[IRP_MJ_PNP] = common_pnp_dispatch; - build_initial_deviceset(); - return STATUS_SUCCESS; + if (!(events[0] = CreateEventW(NULL, TRUE, FALSE, NULL))) + goto error; + if (!(events[1] = CreateThread(NULL, 0, deviceloop_thread, events[0], 0, NULL))) + { + CloseHandle(events[0]); + goto error; + } + + result = WaitForMultipleObjects(2, events, FALSE, INFINITE); + CloseHandle(events[0]); + CloseHandle(events[1]); + if (result == WAIT_OBJECT_0) + { + TRACE("Initialization successful\n"); + return STATUS_SUCCESS; + } + +error: + ERR("Failed to initialize udev device thread\n"); + udev_unref(udev_context); + udev_context = NULL; + udev_driver_obj = NULL; + return STATUS_UNSUCCESSFUL; } #else -- 2.9.0 From sebastian at fds-team.de Mon Oct 3 06:27:36 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Mon, 3 Oct 2016 13:27:36 +0200 Subject: [2/3] winebus.sys: Watch for hid raw device addition and removal. (v9) Message-ID: <863d53aa-4f00-bf00-4a65-d3be0aa8de24@fds-team.de> From: Aric Stewart Signed-off-by: Aric Stewart Signed-off-by: Sebastian Lackner --- First part of 126774. Besides splitting, I've also done the following changes: * Attempt to include both poll.h and sys/poll.h. This is also what is done in other parts of Wine which make use of poll(), like ws2_32. * Add a function for device removal, instead of adding code directly to the poll loop. The code for it will follow in the next patch. * Move monitor init / event processing code into separate functions - I feel like this makes the code much more readable. It will also be easier to process additional events (for example for shutdown) later. * Do not fail initialization when we cannot create a monitor - as pointed out in a previous mails, just using the initial device set might also work in some cases. * Do not use a pollfd array yet - so far we only need a single element. * Some style improvements. dlls/winebus.sys/bus_udev.c | 80 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 1f6df6f..dae165d 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -26,6 +26,12 @@ #ifdef HAVE_UNISTD_H # include #endif +#ifdef HAVE_POLL_H +# include +#endif +#ifdef HAVE_SYS_POLL_H +# include +#endif #ifdef HAVE_LIBUDEV_H # include #endif @@ -129,6 +135,11 @@ static void try_add_device(struct udev_device *dev) HeapFree(GetProcessHeap(), 0, serial); } +static void try_remove_device(struct udev_device *dev) +{ + /* FIXME */ +} + static void build_initial_deviceset(void) { struct udev_enumerate *enumerate; @@ -164,13 +175,82 @@ static void build_initial_deviceset(void) udev_enumerate_unref(enumerate); } +static struct udev_monitor *create_monitor(struct pollfd *pfd) +{ + struct udev_monitor *monitor; + + monitor = udev_monitor_new_from_netlink(udev_context, "udev"); + if (!monitor) + { + WARN("Unable to get udev monitor object\n"); + return NULL; + } + + if (udev_monitor_filter_add_match_subsystem_devtype(monitor, "hidraw", NULL) < 0) + WARN("Failed to add subsystem 'hidraw' to monitor\n"); + + if (udev_monitor_enable_receiving(monitor) < 0) + goto error; + + if ((pfd->fd = udev_monitor_get_fd(monitor)) >= 0) + { + pfd->events = POLLIN; + return monitor; + } + +error: + WARN("Failed to start monitoring\n"); + udev_monitor_unref(monitor); + return NULL; +} + +static void process_monitor_event(struct udev_monitor *monitor) +{ + struct udev_device *dev; + const char *action; + + dev = udev_monitor_receive_device(monitor); + if (!dev) + { + FIXME("Failed to get device that has changed\n"); + return; + } + + action = udev_device_get_action(dev); + TRACE("Received action %s for udev device %s\n", debugstr_a(action), + debugstr_a(udev_device_get_devnode(dev))); + + if (!action) + WARN("No action received\n"); + else if (strcmp(action, "add") == 0) + try_add_device(dev); + else if (strcmp(action, "remove") == 0) + try_remove_device(dev); + else + WARN("Unhandled action %s\n", debugstr_a(action)); + + udev_device_unref(dev); +} + static DWORD CALLBACK deviceloop_thread(void *args) { + struct udev_monitor *monitor; HANDLE init_done = args; + struct pollfd pfd; + monitor = create_monitor(&pfd); build_initial_deviceset(); SetEvent(init_done); + while (monitor) + { + if (poll(&pfd, 1, -1) <= 0) continue; + process_monitor_event(monitor); + } + + TRACE("Monitor thread exiting\n"); + if (monitor) + udev_monitor_unref(monitor); return 0; } -- 2.9.0 From sebastian at fds-team.de Mon Oct 3 06:29:49 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Mon, 3 Oct 2016 13:29:49 +0200 Subject: [3/3] winebus.sys: Add implementation for device removal. (v9) Message-ID: From: Aric Stewart Signed-off-by: Aric Stewart Signed-off-by: Sebastian Lackner --- Second part of 126774. Besides splitting, I've also done the following changes: * Rename find_hid_device -> bus_find_hid_device, for consistency with other bus_*_hid_*() functions. * Do not append timestamp to the device names. To make the code more robust, I've modified bus_remove_hid_device() to defer the release of the pnp_device pointer. If there are more problems I would prefer to fix them properly, adding the timestamp seems more like a hack to me. * Some style improvements. @Aric: I'm not sure if you are aware of it, but there is currently still a bug somewhere which causes a crash during RemovalRelations when trying to remove a driver which was never added properly. I feel like the right place to fix that is somewhere in ntoskrnl. Are you aware of this issue? dlls/winebus.sys/bus.h | 16 +++++++-- dlls/winebus.sys/bus_udev.c | 38 ++++++++++++++++++++-- dlls/winebus.sys/main.c | 74 ++++++++++++++++++++++++++++++++++++++------ 3 files changed, 111 insertions(+), 17 deletions(-) diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index dcb50f2..099558b 100644 --- a/dlls/winebus.sys/bus.h +++ b/dlls/winebus.sys/bus.h @@ -19,8 +19,18 @@ /* Busses */ NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path) DECLSPEC_HIDDEN; +/* Native device function table */ +typedef struct +{ + int (*compare_platform_device)(DEVICE_OBJECT *device, void *platform_dev); +} platform_vtbl; + +void *get_platform_private(DEVICE_OBJECT *device) DECLSPEC_HIDDEN; + /* HID Plug and Play Bus */ NTSTATUS WINAPI common_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN; -DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, void *native, WORD vid, - WORD pid, DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad, - const GUID *class) DECLSPEC_HIDDEN; +DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, WORD vid, WORD pid, + DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad, + const GUID *class, const platform_vtbl *vtbl, DWORD platform_data_size) DECLSPEC_HIDDEN; +DEVICE_OBJECT *bus_find_hid_device(const platform_vtbl *vtbl, void *platform_dev) DECLSPEC_HIDDEN; +void bus_remove_hid_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN; diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index b1d6c3f..d798c53 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -61,6 +61,16 @@ static const WCHAR hidraw_busidW[] = {'H','I','D','R','A','W',0}; #include "initguid.h" DEFINE_GUID(GUID_DEVCLASS_HIDRAW, 0x3def44ad,0x242e,0x46e5,0x82,0x6d,0x70,0x72,0x13,0xf3,0xaa,0x81); +struct platform_private +{ + struct udev_device *udev_device; +}; + +static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device) +{ + return (struct platform_private *)get_platform_private(device); +} + static DWORD get_sysattr_dword(struct udev_device *dev, const char *sysattr, int base) { const char *attr = udev_device_get_sysattr_value(dev, sysattr); @@ -88,6 +98,18 @@ static WCHAR *get_sysattr_string(struct udev_device *dev, const char *sysattr) return dst; } +static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev) +{ + struct udev_device *dev1 = impl_from_DEVICE_OBJECT(device)->udev_device; + struct udev_device *dev2 = platform_dev; + return strcmp(udev_device_get_syspath(dev1), udev_device_get_syspath(dev2)); +} + +static const platform_vtbl hidraw_vtbl = +{ + compare_platform_device, +}; + static void try_add_device(struct udev_device *dev) { DWORD vid = 0, pid = 0, version = 0; @@ -123,12 +145,15 @@ static void try_add_device(struct udev_device *dev) subsystem = udev_device_get_subsystem(dev); if (strcmp(subsystem, "hidraw") == 0) { - device = bus_create_hid_device(udev_driver_obj, hidraw_busidW, dev, vid, pid, - version, 0, serial, FALSE, &GUID_DEVCLASS_HIDRAW); + device = bus_create_hid_device(udev_driver_obj, hidraw_busidW, vid, pid, version, 0, serial, FALSE, + &GUID_DEVCLASS_HIDRAW, &hidraw_vtbl, sizeof(struct platform_private)); } if (device) - udev_device_ref(dev); + { + impl_from_DEVICE_OBJECT(device)->udev_device = udev_device_ref(dev); + IoInvalidateDeviceRelations(device, BusRelations); + } else WARN("Ignoring device %s with subsystem %s\n", debugstr_a(devnode), subsystem); @@ -137,7 +162,12 @@ static void try_add_device(struct udev_device *dev) static void try_remove_device(struct udev_device *dev) { - /* FIXME */ + DEVICE_OBJECT *device = bus_find_hid_device(&hidraw_vtbl, dev); + if (!device) return; + + dev = impl_from_DEVICE_OBJECT(device)->udev_device; + bus_remove_hid_device(device); + udev_device_unref(dev); } static void build_initial_deviceset(void) diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index 1364eab..09a59d6 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -47,13 +47,16 @@ struct pnp_device struct device_extension { - void *native; /* Must be the first member of the structure */ + struct pnp_device *pnp_device; WORD vid, pid; DWORD uid, version, index; BOOL is_gamepad; WCHAR *serial; const WCHAR *busid; /* Expected to be a static constant */ + + const platform_vtbl *vtbl; + BYTE platform_private[1]; }; static CRITICAL_SECTION device_list_cs; @@ -80,6 +83,12 @@ static inline WCHAR *strdupW(const WCHAR *src) return dst; } +void *get_platform_private(DEVICE_OBJECT *device) +{ + struct device_extension *ext = (struct device_extension *)device->DeviceExtension; + return ext->platform_private; +} + static DWORD get_vidpid_index(WORD vid, WORD pid) { struct pnp_device *ptr; @@ -157,9 +166,9 @@ static WCHAR *get_compatible_ids(DEVICE_OBJECT *device) return dst; } -DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, void *native, WORD vid, - WORD pid, DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad, - const GUID *class) +DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, WORD vid, WORD pid, + DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad, + const GUID *class, const platform_vtbl *vtbl, DWORD platform_data_size) { static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e','\\','%','s','#','%','p',0}; struct device_extension *ext; @@ -169,16 +178,18 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, WCHAR dev_name[256]; HDEVINFO devinfo; NTSTATUS status; + DWORD length; - TRACE("(%p, %s, %p, %04x, %04x, %u, %u, %s, %u, %s)\n", driver, debugstr_w(busidW), native, - vid, pid, version, uid, debugstr_w(serialW), is_gamepad, debugstr_guid(class)); + TRACE("(%p, %s, %04x, %04x, %u, %u, %s, %u, %s, %p, %u)\n", driver, debugstr_w(busidW), vid, pid, + version, uid, debugstr_w(serialW), is_gamepad, debugstr_guid(class), vtbl, platform_data_size); if (!(pnp_dev = HeapAlloc(GetProcessHeap(), 0, sizeof(*pnp_dev)))) return NULL; - sprintfW(dev_name, device_name_fmtW, busidW, native); + sprintfW(dev_name, device_name_fmtW, busidW, pnp_dev); RtlInitUnicodeString(&nameW, dev_name); - status = IoCreateDevice(driver, sizeof(*ext), &nameW, 0, 0, FALSE, &device); + length = FIELD_OFFSET(struct device_extension, platform_private[platform_data_size]); + status = IoCreateDevice(driver, length, &nameW, 0, 0, FALSE, &device); if (status) { FIXME("failed to create device error %x\n", status); @@ -190,7 +201,7 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, /* fill out device_extension struct */ ext = (struct device_extension *)device->DeviceExtension; - ext->native = native; + ext->pnp_device = pnp_dev; ext->vid = vid; ext->pid = pid; ext->uid = uid; @@ -199,6 +210,7 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, ext->is_gamepad = is_gamepad; ext->serial = strdupW(serialW); ext->busid = busidW; + ext->vtbl = vtbl; /* add to list of pnp devices */ pnp_dev->device = device; @@ -226,10 +238,52 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, else ERR("failed to get ClassDevs: %x\n", GetLastError()); - IoInvalidateDeviceRelations(device, BusRelations); return device; } +DEVICE_OBJECT *bus_find_hid_device(const platform_vtbl *vtbl, void *platform_dev) +{ + struct pnp_device *dev; + DEVICE_OBJECT *ret = NULL; + + TRACE("(%p, %p)\n", vtbl, platform_dev); + + EnterCriticalSection(&device_list_cs); + LIST_FOR_EACH_ENTRY(dev, &pnp_devset, struct pnp_device, entry) + { + struct device_extension *ext = (struct device_extension *)dev->device->DeviceExtension; + if (ext->vtbl != vtbl) continue; + if (ext->vtbl->compare_platform_device(dev->device, platform_dev) == 0) + { + ret = dev->device; + break; + } + } + LeaveCriticalSection(&device_list_cs); + + TRACE("returning %p\n", ret); + return ret; +} + +void bus_remove_hid_device(DEVICE_OBJECT *device) +{ + struct device_extension *ext = (struct device_extension *)device->DeviceExtension; + struct pnp_device *pnp_device = ext->pnp_device; + + TRACE("(%p)\n", device); + + EnterCriticalSection(&device_list_cs); + list_remove(&pnp_device->entry); + LeaveCriticalSection(&device_list_cs); + + IoInvalidateDeviceRelations(device, RemovalRelations); + HeapFree(GetProcessHeap(), 0, ext->serial); + IoDeleteDevice(device); + + /* pnp_device must be released after the device is gone */ + HeapFree(GetProcessHeap(), 0, pnp_device); +} + static NTSTATUS handle_IRP_MN_QUERY_ID(DEVICE_OBJECT *device, IRP *irp) { NTSTATUS status = irp->IoStatus.u.Status; -- 2.9.0 From sebastian at fds-team.de Mon Oct 3 06:49:31 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Mon, 3 Oct 2016 13:49:31 +0200 Subject: kernel32/tests: Add a testcase for CreateFileA with an invalid path. Message-ID: Spotted by Christoph von Wittich. Signed-off-by: Sebastian Lackner --- See https://bugs.winehq.org/show_bug.cgi?id=41395. It should not matter if it is a valid drive letter in this case. dlls/kernel32/tests/file.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index 5327865..f039cf9 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -1206,20 +1206,22 @@ static void test_CreateFileA(void) char directory[] = "removeme"; static const char nt_drive[] = "\\\\?\\A:"; DWORD i, ret, len; - struct test_list p[] = { - {"", ERROR_PATH_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, TRUE }, /* dir as file w \ */ - {"", ERROR_SUCCESS, ERROR_PATH_NOT_FOUND, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* dir as dir w \ */ - {"a", ERROR_FILE_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, FALSE }, /* non-exist file */ - {"a\\", ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND, FILE_ATTRIBUTE_NORMAL, FALSE }, /* non-exist dir */ - {"removeme", ERROR_ACCESS_DENIED, -1, FILE_ATTRIBUTE_NORMAL, FALSE }, /* exist dir w/o \ */ - {"removeme\\", ERROR_PATH_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, TRUE }, /* exst dir w \ */ - {"c:", ERROR_ACCESS_DENIED, ERROR_PATH_NOT_FOUND, FILE_ATTRIBUTE_NORMAL, FALSE }, /* device in file namespace */ - {"c:", ERROR_SUCCESS, ERROR_PATH_NOT_FOUND, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* device in file namespace as dir */ - {"c:\\", ERROR_PATH_NOT_FOUND, ERROR_ACCESS_DENIED, FILE_ATTRIBUTE_NORMAL, TRUE }, /* root dir w \ */ - {"c:\\", ERROR_SUCCESS, ERROR_ACCESS_DENIED, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* root dir w \ as dir */ - {"\\\\?\\c:", ERROR_SUCCESS, ERROR_BAD_NETPATH, FILE_ATTRIBUTE_NORMAL,FALSE }, /* dev namespace drive */ - {"\\\\?\\c:\\", ERROR_PATH_NOT_FOUND, ERROR_BAD_NETPATH, FILE_ATTRIBUTE_NORMAL, TRUE }, /* dev namespace drive w \ */ - {NULL, 0, -1, 0, FALSE} + static const struct test_list p[] = + { + {"", ERROR_PATH_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, TRUE }, /* dir as file w \ */ + {"", ERROR_SUCCESS, ERROR_PATH_NOT_FOUND, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* dir as dir w \ */ + {"a", ERROR_FILE_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, FALSE }, /* non-exist file */ + {"a\\", ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND, FILE_ATTRIBUTE_NORMAL, FALSE }, /* non-exist dir */ + {"removeme", ERROR_ACCESS_DENIED, -1, FILE_ATTRIBUTE_NORMAL, FALSE }, /* exist dir w/o \ */ + {"removeme\\", ERROR_PATH_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, TRUE }, /* exst dir w \ */ + {"c:", ERROR_ACCESS_DENIED, ERROR_PATH_NOT_FOUND, FILE_ATTRIBUTE_NORMAL, FALSE }, /* device in file namespace */ + {"c:", ERROR_SUCCESS, ERROR_PATH_NOT_FOUND, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* device in file namespace as dir */ + {"c:\\", ERROR_PATH_NOT_FOUND, ERROR_ACCESS_DENIED, FILE_ATTRIBUTE_NORMAL, TRUE }, /* root dir w \ */ + {"c:\\", ERROR_SUCCESS, ERROR_ACCESS_DENIED, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* root dir w \ as dir */ + {"c:c:\\windows", ERROR_INVALID_NAME, -1, FILE_ATTRIBUTE_NORMAL, TRUE }, /* invalid path */ + {"\\\\?\\c:", ERROR_SUCCESS, ERROR_BAD_NETPATH, FILE_ATTRIBUTE_NORMAL,FALSE }, /* dev namespace drive */ + {"\\\\?\\c:\\", ERROR_PATH_NOT_FOUND, ERROR_BAD_NETPATH, FILE_ATTRIBUTE_NORMAL, TRUE }, /* dev namespace drive w \ */ + {NULL, 0, -1, 0, FALSE} }; BY_HANDLE_FILE_INFORMATION Finfo; WCHAR curdir[MAX_PATH]; -- 2.9.0 From nerv at dawncrow.de Mon Oct 3 07:12:39 2016 From: nerv at dawncrow.de (=?UTF-8?Q?Andr=c3=a9_Hentschel?=) Date: Mon, 3 Oct 2016 14:12:39 +0200 Subject: advapi32/tests: Don't crash the service test on wow64 Wine Message-ID: <2501a590-2cac-9918-b6ef-c864c3a3e3a0@dawncrow.de> Signed-off-by: André Hentschel --- dlls/advapi32/tests/service.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-advapi32-tests-Don-t-crash-the-service-test-on-wow64-W.txt Type: text/x-patch Size: 1210 bytes Desc: not available URL: From sebastian at fds-team.de Mon Oct 3 07:44:47 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Mon, 3 Oct 2016 14:44:47 +0200 Subject: advapi32/tests: Don't crash the service test on wow64 Wine In-Reply-To: <2501a590-2cac-9918-b6ef-c864c3a3e3a0@dawncrow.de> References: <2501a590-2cac-9918-b6ef-c864c3a3e3a0@dawncrow.de> Message-ID: <782af152-9728-39a8-0b9f-35d7d622259b@fds-team.de> On 03.10.2016 14:12, André Hentschel wrote: > Signed-off-by: André Hentschel > --- > dlls/advapi32/tests/service.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) I've looked at this issue before, the reason is a marshalling problem (struct size different on 32-bit and 64-bit). I haven't had time to figure out how it works on Windows yet. Signed-off-by: Sebastian Lackner From hverbeet at codeweavers.com Mon Oct 3 08:45:44 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 3 Oct 2016 15:45:44 +0200 Subject: [PATCH 3/6] ddraw/tests: Test d3d2 and 3 drawing with non-standard viewports (v2). In-Reply-To: <1475343572-5997-3-git-send-email-stefandoesinger@gmx.at> References: <1475343572-5997-3-git-send-email-stefandoesinger@gmx.at> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 3 08:45:45 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 3 Oct 2016 15:45:45 +0200 Subject: [PATCH 1/6] ddraw/tests: Add position tests for D3DPROCESSVERTICES_TRANSFORM (v2). In-Reply-To: <1475343572-5997-1-git-send-email-stefandoesinger@gmx.at> References: <1475343572-5997-1-git-send-email-stefandoesinger@gmx.at> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 3 08:45:47 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 3 Oct 2016 15:45:47 +0200 Subject: [PATCH 4/6] ddraw: Apply legacy clipspace to d3d2. In-Reply-To: <1475343572-5997-4-git-send-email-stefandoesinger@gmx.at> References: <1475343572-5997-4-git-send-email-stefandoesinger@gmx.at> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 3 08:45:48 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 3 Oct 2016 15:45:48 +0200 Subject: [PATCH 6/6] ddraw/tests: Add D3DVIEWPORT2 transform tests. In-Reply-To: <1475343572-5997-6-git-send-email-stefandoesinger@gmx.at> References: <1475343572-5997-6-git-send-email-stefandoesinger@gmx.at> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 3 08:45:49 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 3 Oct 2016 15:45:49 +0200 Subject: [PATCH 5/6] ddraw: Use the clip space matrix in TransformVertices. In-Reply-To: <1475343572-5997-5-git-send-email-stefandoesinger@gmx.at> References: <1475343572-5997-5-git-send-email-stefandoesinger@gmx.at> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 3 08:45:46 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 3 Oct 2016 15:45:46 +0200 Subject: [PATCH 2/6] ddraw: Store d3d1 projection matrices in device->legacy_projection. In-Reply-To: <1475343572-5997-2-git-send-email-stefandoesinger@gmx.at> References: <1475343572-5997-2-git-send-email-stefandoesinger@gmx.at> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 3 08:45:50 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 3 Oct 2016 15:45:50 +0200 Subject: [PATCH 1/7] wined3d: Use MAX_TEXTURES instead of magic number. In-Reply-To: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> References: <1475447922-2579-1-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 3 08:45:50 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 3 Oct 2016 15:45:50 +0200 Subject: [PATCH 2/7] wined3d: Do not create separate dummy texture for each texture image unit. In-Reply-To: <1475447922-2579-2-git-send-email-jkucia@codeweavers.com> References: <1475447922-2579-2-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 3 08:45:51 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 3 Oct 2016 15:45:51 +0200 Subject: [PATCH 3/7] wined3d: Bind dummy textures to all texture image units. In-Reply-To: <1475447922-2579-3-git-send-email-jkucia@codeweavers.com> References: <1475447922-2579-3-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 3 08:45:52 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 3 Oct 2016 15:45:52 +0200 Subject: [PATCH 5/7] wined3d: Pass context to create_default_samplers(). In-Reply-To: <1475447922-2579-5-git-send-email-jkucia@codeweavers.com> References: <1475447922-2579-5-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From aric at codeweavers.com Mon Oct 3 10:29:41 2016 From: aric at codeweavers.com (Aric Stewart) Date: Mon, 3 Oct 2016 10:29:41 -0500 Subject: [1/3] winebus.sys: Spawn a device loop thread and add synchronization. In-Reply-To: <60d6665a-7f1a-962f-f23b-831f555062d2@fds-team.de> References: <60d6665a-7f1a-962f-f23b-831f555062d2@fds-team.de> Message-ID: Signed-off-by: Aric Stewart On 10/3/16 6:24 AM, Sebastian Lackner wrote: > Signed-off-by: Sebastian Lackner > --- > > Alexandres remark that we should probably build the initial deviceset from > the monitor thread is valid, and I have also thought about that in the past. > Nevertheless, I think it is a good idea to have some synchronization at least, > so that we do not proceed with the execution until we are done with the > initialization. > > dlls/winebus.sys/bus_udev.c | 38 ++++++++++++++++++++++++++++++++++++-- > 1 file changed, 36 insertions(+), 2 deletions(-) > > diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c > index 1525861..1f6df6f 100644 > --- a/dlls/winebus.sys/bus_udev.c > +++ b/dlls/winebus.sys/bus_udev.c > @@ -164,8 +164,21 @@ static void build_initial_deviceset(void) > udev_enumerate_unref(enumerate); > } > > +static DWORD CALLBACK deviceloop_thread(void *args) > +{ > + HANDLE init_done = args; > + > + build_initial_deviceset(); > + SetEvent(init_done); > + > + return 0; > +} > + > NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path) > { > + HANDLE events[2]; > + DWORD result; > + > TRACE("(%p, %s)\n", driver, debugstr_w(registry_path->Buffer)); > > if (!(udev_context = udev_new())) > @@ -177,8 +190,29 @@ NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry > udev_driver_obj = driver; > driver->MajorFunction[IRP_MJ_PNP] = common_pnp_dispatch; > > - build_initial_deviceset(); > - return STATUS_SUCCESS; > + if (!(events[0] = CreateEventW(NULL, TRUE, FALSE, NULL))) > + goto error; > + if (!(events[1] = CreateThread(NULL, 0, deviceloop_thread, events[0], 0, NULL))) > + { > + CloseHandle(events[0]); > + goto error; > + } > + > + result = WaitForMultipleObjects(2, events, FALSE, INFINITE); > + CloseHandle(events[0]); > + CloseHandle(events[1]); > + if (result == WAIT_OBJECT_0) > + { > + TRACE("Initialization successful\n"); > + return STATUS_SUCCESS; > + } > + > +error: > + ERR("Failed to initialize udev device thread\n"); > + udev_unref(udev_context); > + udev_context = NULL; > + udev_driver_obj = NULL; > + return STATUS_UNSUCCESSFUL; > } > > #else > From aric at codeweavers.com Mon Oct 3 10:31:04 2016 From: aric at codeweavers.com (Aric Stewart) Date: Mon, 3 Oct 2016 10:31:04 -0500 Subject: [2/3] winebus.sys: Watch for hid raw device addition and removal. (v9) In-Reply-To: <863d53aa-4f00-bf00-4a65-d3be0aa8de24@fds-team.de> References: <863d53aa-4f00-bf00-4a65-d3be0aa8de24@fds-team.de> Message-ID: <8ff47e3e-39cc-2b29-3823-7c11483e08d3@codeweavers.com> Signed-off-by: Aric Stewart On 10/3/16 6:27 AM, Sebastian Lackner wrote: > From: Aric Stewart > > Signed-off-by: Aric Stewart > Signed-off-by: Sebastian Lackner > --- > > First part of 126774. Besides splitting, I've also done the following changes: > > * Attempt to include both poll.h and sys/poll.h. This is also what is done in other > parts of Wine which make use of poll(), like ws2_32. > * Add a function for device removal, instead of adding code directly to the poll loop. > The code for it will follow in the next patch. > * Move monitor init / event processing code into separate functions - I feel like this > makes the code much more readable. It will also be easier to process additional > events (for example for shutdown) later. > * Do not fail initialization when we cannot create a monitor - as pointed out in a > previous mails, just using the initial device set might also work in some cases. > * Do not use a pollfd array yet - so far we only need a single element. > * Some style improvements. > > dlls/winebus.sys/bus_udev.c | 80 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 80 insertions(+) > > diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c > index 1f6df6f..dae165d 100644 > --- a/dlls/winebus.sys/bus_udev.c > +++ b/dlls/winebus.sys/bus_udev.c > @@ -26,6 +26,12 @@ > #ifdef HAVE_UNISTD_H > # include > #endif > +#ifdef HAVE_POLL_H > +# include > +#endif > +#ifdef HAVE_SYS_POLL_H > +# include > +#endif > #ifdef HAVE_LIBUDEV_H > # include > #endif > @@ -129,6 +135,11 @@ static void try_add_device(struct udev_device *dev) > HeapFree(GetProcessHeap(), 0, serial); > } > > +static void try_remove_device(struct udev_device *dev) > +{ > + /* FIXME */ > +} > + > static void build_initial_deviceset(void) > { > struct udev_enumerate *enumerate; > @@ -164,13 +175,82 @@ static void build_initial_deviceset(void) > udev_enumerate_unref(enumerate); > } > > +static struct udev_monitor *create_monitor(struct pollfd *pfd) > +{ > + struct udev_monitor *monitor; > + > + monitor = udev_monitor_new_from_netlink(udev_context, "udev"); > + if (!monitor) > + { > + WARN("Unable to get udev monitor object\n"); > + return NULL; > + } > + > + if (udev_monitor_filter_add_match_subsystem_devtype(monitor, "hidraw", NULL) < 0) > + WARN("Failed to add subsystem 'hidraw' to monitor\n"); > + > + if (udev_monitor_enable_receiving(monitor) < 0) > + goto error; > + > + if ((pfd->fd = udev_monitor_get_fd(monitor)) >= 0) > + { > + pfd->events = POLLIN; > + return monitor; > + } > + > +error: > + WARN("Failed to start monitoring\n"); > + udev_monitor_unref(monitor); > + return NULL; > +} > + > +static void process_monitor_event(struct udev_monitor *monitor) > +{ > + struct udev_device *dev; > + const char *action; > + > + dev = udev_monitor_receive_device(monitor); > + if (!dev) > + { > + FIXME("Failed to get device that has changed\n"); > + return; > + } > + > + action = udev_device_get_action(dev); > + TRACE("Received action %s for udev device %s\n", debugstr_a(action), > + debugstr_a(udev_device_get_devnode(dev))); > + > + if (!action) > + WARN("No action received\n"); > + else if (strcmp(action, "add") == 0) > + try_add_device(dev); > + else if (strcmp(action, "remove") == 0) > + try_remove_device(dev); > + else > + WARN("Unhandled action %s\n", debugstr_a(action)); > + > + udev_device_unref(dev); > +} > + > static DWORD CALLBACK deviceloop_thread(void *args) > { > + struct udev_monitor *monitor; > HANDLE init_done = args; > + struct pollfd pfd; > > + monitor = create_monitor(&pfd); > build_initial_deviceset(); > SetEvent(init_done); > > + while (monitor) > + { > + if (poll(&pfd, 1, -1) <= 0) continue; > + process_monitor_event(monitor); > + } > + > + TRACE("Monitor thread exiting\n"); > + if (monitor) > + udev_monitor_unref(monitor); > return 0; > } > > From aric at codeweavers.com Mon Oct 3 10:33:22 2016 From: aric at codeweavers.com (Aric Stewart) Date: Mon, 3 Oct 2016 10:33:22 -0500 Subject: [3/3] winebus.sys: Add implementation for device removal. (v9) In-Reply-To: References: Message-ID: <511ba0ef-ad6a-729d-ec98-4732006dd5b5@codeweavers.com> Signed-off-by: Aric Stewart On 10/3/16 6:29 AM, Sebastian Lackner wrote: > From: Aric Stewart > > Signed-off-by: Aric Stewart > Signed-off-by: Sebastian Lackner > --- > > Second part of 126774. Besides splitting, I've also done the following changes: > > * Rename find_hid_device -> bus_find_hid_device, for consistency with other bus_*_hid_*() functions. > * Do not append timestamp to the device names. To make the code more robust, I've modified > bus_remove_hid_device() to defer the release of the pnp_device pointer. If there are more > problems I would prefer to fix them properly, adding the timestamp seems more like a hack to me. > * Some style improvements. > > @Aric: I'm not sure if you are aware of it, but there is currently still a bug somewhere which > causes a crash during RemovalRelations when trying to remove a driver which was never added properly. > I feel like the right place to fix that is somewhere in ntoskrnl. Are you aware of this issue? > > dlls/winebus.sys/bus.h | 16 +++++++-- > dlls/winebus.sys/bus_udev.c | 38 ++++++++++++++++++++-- > dlls/winebus.sys/main.c | 74 ++++++++++++++++++++++++++++++++++++++------ > 3 files changed, 111 insertions(+), 17 deletions(-) > > diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h > index dcb50f2..099558b 100644 > --- a/dlls/winebus.sys/bus.h > +++ b/dlls/winebus.sys/bus.h > @@ -19,8 +19,18 @@ > /* Busses */ > NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path) DECLSPEC_HIDDEN; > > +/* Native device function table */ > +typedef struct > +{ > + int (*compare_platform_device)(DEVICE_OBJECT *device, void *platform_dev); > +} platform_vtbl; > + > +void *get_platform_private(DEVICE_OBJECT *device) DECLSPEC_HIDDEN; > + > /* HID Plug and Play Bus */ > NTSTATUS WINAPI common_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN; > -DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, void *native, WORD vid, > - WORD pid, DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad, > - const GUID *class) DECLSPEC_HIDDEN; > +DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, WORD vid, WORD pid, > + DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad, > + const GUID *class, const platform_vtbl *vtbl, DWORD platform_data_size) DECLSPEC_HIDDEN; > +DEVICE_OBJECT *bus_find_hid_device(const platform_vtbl *vtbl, void *platform_dev) DECLSPEC_HIDDEN; > +void bus_remove_hid_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN; > diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c > index b1d6c3f..d798c53 100644 > --- a/dlls/winebus.sys/bus_udev.c > +++ b/dlls/winebus.sys/bus_udev.c > @@ -61,6 +61,16 @@ static const WCHAR hidraw_busidW[] = {'H','I','D','R','A','W',0}; > #include "initguid.h" > DEFINE_GUID(GUID_DEVCLASS_HIDRAW, 0x3def44ad,0x242e,0x46e5,0x82,0x6d,0x70,0x72,0x13,0xf3,0xaa,0x81); > > +struct platform_private > +{ > + struct udev_device *udev_device; > +}; > + > +static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device) > +{ > + return (struct platform_private *)get_platform_private(device); > +} > + > static DWORD get_sysattr_dword(struct udev_device *dev, const char *sysattr, int base) > { > const char *attr = udev_device_get_sysattr_value(dev, sysattr); > @@ -88,6 +98,18 @@ static WCHAR *get_sysattr_string(struct udev_device *dev, const char *sysattr) > return dst; > } > > +static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev) > +{ > + struct udev_device *dev1 = impl_from_DEVICE_OBJECT(device)->udev_device; > + struct udev_device *dev2 = platform_dev; > + return strcmp(udev_device_get_syspath(dev1), udev_device_get_syspath(dev2)); > +} > + > +static const platform_vtbl hidraw_vtbl = > +{ > + compare_platform_device, > +}; > + > static void try_add_device(struct udev_device *dev) > { > DWORD vid = 0, pid = 0, version = 0; > @@ -123,12 +145,15 @@ static void try_add_device(struct udev_device *dev) > subsystem = udev_device_get_subsystem(dev); > if (strcmp(subsystem, "hidraw") == 0) > { > - device = bus_create_hid_device(udev_driver_obj, hidraw_busidW, dev, vid, pid, > - version, 0, serial, FALSE, &GUID_DEVCLASS_HIDRAW); > + device = bus_create_hid_device(udev_driver_obj, hidraw_busidW, vid, pid, version, 0, serial, FALSE, > + &GUID_DEVCLASS_HIDRAW, &hidraw_vtbl, sizeof(struct platform_private)); > } > > if (device) > - udev_device_ref(dev); > + { > + impl_from_DEVICE_OBJECT(device)->udev_device = udev_device_ref(dev); > + IoInvalidateDeviceRelations(device, BusRelations); > + } > else > WARN("Ignoring device %s with subsystem %s\n", debugstr_a(devnode), subsystem); > > @@ -137,7 +162,12 @@ static void try_add_device(struct udev_device *dev) > > static void try_remove_device(struct udev_device *dev) > { > - /* FIXME */ > + DEVICE_OBJECT *device = bus_find_hid_device(&hidraw_vtbl, dev); > + if (!device) return; > + > + dev = impl_from_DEVICE_OBJECT(device)->udev_device; > + bus_remove_hid_device(device); > + udev_device_unref(dev); > } > > static void build_initial_deviceset(void) > diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c > index 1364eab..09a59d6 100644 > --- a/dlls/winebus.sys/main.c > +++ b/dlls/winebus.sys/main.c > @@ -47,13 +47,16 @@ struct pnp_device > > struct device_extension > { > - void *native; /* Must be the first member of the structure */ > + struct pnp_device *pnp_device; > > WORD vid, pid; > DWORD uid, version, index; > BOOL is_gamepad; > WCHAR *serial; > const WCHAR *busid; /* Expected to be a static constant */ > + > + const platform_vtbl *vtbl; > + BYTE platform_private[1]; > }; > > static CRITICAL_SECTION device_list_cs; > @@ -80,6 +83,12 @@ static inline WCHAR *strdupW(const WCHAR *src) > return dst; > } > > +void *get_platform_private(DEVICE_OBJECT *device) > +{ > + struct device_extension *ext = (struct device_extension *)device->DeviceExtension; > + return ext->platform_private; > +} > + > static DWORD get_vidpid_index(WORD vid, WORD pid) > { > struct pnp_device *ptr; > @@ -157,9 +166,9 @@ static WCHAR *get_compatible_ids(DEVICE_OBJECT *device) > return dst; > } > > -DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, void *native, WORD vid, > - WORD pid, DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad, > - const GUID *class) > +DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, WORD vid, WORD pid, > + DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad, > + const GUID *class, const platform_vtbl *vtbl, DWORD platform_data_size) > { > static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e','\\','%','s','#','%','p',0}; > struct device_extension *ext; > @@ -169,16 +178,18 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, > WCHAR dev_name[256]; > HDEVINFO devinfo; > NTSTATUS status; > + DWORD length; > > - TRACE("(%p, %s, %p, %04x, %04x, %u, %u, %s, %u, %s)\n", driver, debugstr_w(busidW), native, > - vid, pid, version, uid, debugstr_w(serialW), is_gamepad, debugstr_guid(class)); > + TRACE("(%p, %s, %04x, %04x, %u, %u, %s, %u, %s, %p, %u)\n", driver, debugstr_w(busidW), vid, pid, > + version, uid, debugstr_w(serialW), is_gamepad, debugstr_guid(class), vtbl, platform_data_size); > > if (!(pnp_dev = HeapAlloc(GetProcessHeap(), 0, sizeof(*pnp_dev)))) > return NULL; > > - sprintfW(dev_name, device_name_fmtW, busidW, native); > + sprintfW(dev_name, device_name_fmtW, busidW, pnp_dev); > RtlInitUnicodeString(&nameW, dev_name); > - status = IoCreateDevice(driver, sizeof(*ext), &nameW, 0, 0, FALSE, &device); > + length = FIELD_OFFSET(struct device_extension, platform_private[platform_data_size]); > + status = IoCreateDevice(driver, length, &nameW, 0, 0, FALSE, &device); > if (status) > { > FIXME("failed to create device error %x\n", status); > @@ -190,7 +201,7 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, > > /* fill out device_extension struct */ > ext = (struct device_extension *)device->DeviceExtension; > - ext->native = native; > + ext->pnp_device = pnp_dev; > ext->vid = vid; > ext->pid = pid; > ext->uid = uid; > @@ -199,6 +210,7 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, > ext->is_gamepad = is_gamepad; > ext->serial = strdupW(serialW); > ext->busid = busidW; > + ext->vtbl = vtbl; > > /* add to list of pnp devices */ > pnp_dev->device = device; > @@ -226,10 +238,52 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, > else > ERR("failed to get ClassDevs: %x\n", GetLastError()); > > - IoInvalidateDeviceRelations(device, BusRelations); > return device; > } > > +DEVICE_OBJECT *bus_find_hid_device(const platform_vtbl *vtbl, void *platform_dev) > +{ > + struct pnp_device *dev; > + DEVICE_OBJECT *ret = NULL; > + > + TRACE("(%p, %p)\n", vtbl, platform_dev); > + > + EnterCriticalSection(&device_list_cs); > + LIST_FOR_EACH_ENTRY(dev, &pnp_devset, struct pnp_device, entry) > + { > + struct device_extension *ext = (struct device_extension *)dev->device->DeviceExtension; > + if (ext->vtbl != vtbl) continue; > + if (ext->vtbl->compare_platform_device(dev->device, platform_dev) == 0) > + { > + ret = dev->device; > + break; > + } > + } > + LeaveCriticalSection(&device_list_cs); > + > + TRACE("returning %p\n", ret); > + return ret; > +} > + > +void bus_remove_hid_device(DEVICE_OBJECT *device) > +{ > + struct device_extension *ext = (struct device_extension *)device->DeviceExtension; > + struct pnp_device *pnp_device = ext->pnp_device; > + > + TRACE("(%p)\n", device); > + > + EnterCriticalSection(&device_list_cs); > + list_remove(&pnp_device->entry); > + LeaveCriticalSection(&device_list_cs); > + > + IoInvalidateDeviceRelations(device, RemovalRelations); > + HeapFree(GetProcessHeap(), 0, ext->serial); > + IoDeleteDevice(device); > + > + /* pnp_device must be released after the device is gone */ > + HeapFree(GetProcessHeap(), 0, pnp_device); > +} > + > static NTSTATUS handle_IRP_MN_QUERY_ID(DEVICE_OBJECT *device, IRP *irp) > { > NTSTATUS status = irp->IoStatus.u.Status; > From nsivov at codeweavers.com Mon Oct 3 10:56:11 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Mon, 3 Oct 2016 18:56:11 +0300 Subject: [v3 PATCH] d2d1: Initial implementation of HWND render target Message-ID: <20161003155611.3798-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- v3: remove unused function v2: fixed tests failures dlls/d2d1/Makefile.in | 3 +- dlls/d2d1/d2d1_private.h | 17 +- dlls/d2d1/dc_render_target.c | 2 +- dlls/d2d1/factory.c | 25 +- dlls/d2d1/hwnd_render_target.c | 869 +++++++++++++++++++++++++++++++++++++++++ dlls/d2d1/render_target.c | 9 +- dlls/d2d1/tests/d2d1.c | 51 +++ 7 files changed, 970 insertions(+), 6 deletions(-) create mode 100644 dlls/d2d1/hwnd_render_target.c diff --git a/dlls/d2d1/Makefile.in b/dlls/d2d1/Makefile.in index 06f7bde..deacd7a 100644 --- a/dlls/d2d1/Makefile.in +++ b/dlls/d2d1/Makefile.in @@ -1,6 +1,6 @@ MODULE = d2d1.dll IMPORTLIB = d2d1 -IMPORTS = d3d10_1 dxguid uuid gdi32 +IMPORTS = d3d10_1 dxguid uuid gdi32 user32 DELAYIMPORTS = dwrite C_SRCS = \ @@ -9,6 +9,7 @@ C_SRCS = \ dc_render_target.c \ factory.c \ geometry.c \ + hwnd_render_target.c \ mesh.c \ render_target.c \ state_block.c \ diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index fa7e464..6cee5ef 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -96,7 +96,7 @@ struct d2d_d3d_render_target HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory, IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN; -HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN; +HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN; struct d2d_wic_render_target { @@ -131,6 +131,21 @@ struct d2d_dc_render_target HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID2D1Factory *factory, ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN; +struct d2d_hwnd_render_target +{ + ID2D1HwndRenderTarget ID2D1HwndRenderTarget_iface; + LONG refcount; + + ID2D1RenderTarget *dxgi_target; + IDXGISwapChain *swapchain; + UINT sync_interval; + HWND hwnd; +}; + +HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target, ID2D1Factory *factory, + ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc, + const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_desc) DECLSPEC_HIDDEN; + struct d2d_gradient { ID2D1GradientStopCollection ID2D1GradientStopCollection_iface; diff --git a/dlls/d2d1/dc_render_target.c b/dlls/d2d1/dc_render_target.c index ae87a0d..1cf2c8d 100644 --- a/dlls/d2d1/dc_render_target.c +++ b/dlls/d2d1/dc_render_target.c @@ -731,7 +731,7 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget } /* Switch dxgi target to new surface. */ - if (FAILED(hr = d2d_d3d_render_target_update_surface(render_target->dxgi_target, dxgi_surface))) + if (FAILED(hr = d2d_d3d_render_target_create_rtv(render_target->dxgi_target, dxgi_surface))) { WARN("Failed to set new surface, hr %#x.\n", hr); IDXGISurface1_Release(dxgi_surface); diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 66ed25b..86c1690 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -271,9 +271,30 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory const D2D1_RENDER_TARGET_PROPERTIES *desc, const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_rt_desc, ID2D1HwndRenderTarget **render_target) { - FIXME("iface %p, desc %p, hwnd_rt_desc %p, render_target %p stub!\n", iface, desc, hwnd_rt_desc, render_target); + struct d2d_factory *factory = impl_from_ID2D1Factory(iface); + struct d2d_hwnd_render_target *object; + ID3D10Device1 *device; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, desc %p, hwnd_rt_desc %p, render_target %p.\n", iface, desc, hwnd_rt_desc, render_target); + + if (FAILED(hr = d2d_factory_get_device(factory, &device))) + return hr; + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d2d_hwnd_render_target_init(object, iface, device, desc, hwnd_rt_desc))) + { + WARN("Failed to initialize render target, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + TRACE("Created render target %p.\n", object); + *render_target = &object->ID2D1HwndRenderTarget_iface; + + return S_OK; } static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDxgiSurfaceRenderTarget(ID2D1Factory *iface, diff --git a/dlls/d2d1/hwnd_render_target.c b/dlls/d2d1/hwnd_render_target.c new file mode 100644 index 0000000..e9092b6 --- /dev/null +++ b/dlls/d2d1/hwnd_render_target.c @@ -0,0 +1,869 @@ +/* + * Copyright 2014 Henri Verbeet for CodeWeavers + * Copyright 2016 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include "d2d1_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d2d); + +static void render_target_present(struct d2d_hwnd_render_target *render_target) +{ + HRESULT hr; + + if (FAILED(hr = IDXGISwapChain_Present(render_target->swapchain, render_target->sync_interval, 0))) + WARN("Present failed, %#x.\n", hr); +} + +static inline struct d2d_hwnd_render_target *impl_from_ID2D1HwndRenderTarget(ID2D1HwndRenderTarget *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_hwnd_render_target, ID2D1HwndRenderTarget_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_QueryInterface(ID2D1HwndRenderTarget *iface, + REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1HwndRenderTarget) + || IsEqualGUID(iid, &IID_ID2D1RenderTarget) + || IsEqualGUID(iid, &IID_ID2D1Resource) + || IsEqualGUID(iid, &IID_IUnknown)) + { + ID2D1HwndRenderTarget_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_hwnd_render_target_AddRef(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + ULONG refcount = InterlockedIncrement(&render_target->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_hwnd_render_target_Release(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + ULONG refcount = InterlockedDecrement(&render_target->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (!refcount) + { + ID2D1RenderTarget_Release(render_target->dxgi_target); + IDXGISwapChain_Release(render_target->swapchain); + HeapFree(GetProcessHeap(), 0, render_target); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetFactory(ID2D1HwndRenderTarget *iface, ID2D1Factory **factory) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, factory %p.\n", iface, factory); + + ID2D1RenderTarget_GetFactory(render_target->dxgi_target, factory); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateBitmap(ID2D1HwndRenderTarget *iface, + D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, size {%u, %u}, src_data %p, pitch %u, desc %p, bitmap %p.\n", + iface, size.width, size.height, src_data, pitch, desc, bitmap); + + return ID2D1RenderTarget_CreateBitmap(render_target->dxgi_target, size, src_data, pitch, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateBitmapFromWicBitmap(ID2D1HwndRenderTarget *iface, + IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, bitmap_source %p, desc %p, bitmap %p.\n", + iface, bitmap_source, desc, bitmap); + + return ID2D1RenderTarget_CreateBitmapFromWicBitmap(render_target->dxgi_target, bitmap_source, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateSharedBitmap(ID2D1HwndRenderTarget *iface, + REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, iid %s, data %p, desc %p, bitmap %p.\n", + iface, debugstr_guid(iid), data, desc, bitmap); + + return ID2D1RenderTarget_CreateSharedBitmap(render_target->dxgi_target, iid, data, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateBitmapBrush(ID2D1HwndRenderTarget *iface, + ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc, + const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1BitmapBrush **brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p.\n", + iface, bitmap, bitmap_brush_desc, brush_desc, brush); + + return ID2D1RenderTarget_CreateBitmapBrush(render_target->dxgi_target, + bitmap, bitmap_brush_desc, brush_desc, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateSolidColorBrush(ID2D1HwndRenderTarget *iface, + const D2D1_COLOR_F *color, const D2D1_BRUSH_PROPERTIES *desc, ID2D1SolidColorBrush **brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, color %p, desc %p, brush %p.\n", iface, color, desc, brush); + + return ID2D1RenderTarget_CreateSolidColorBrush(render_target->dxgi_target, color, desc, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateGradientStopCollection(ID2D1HwndRenderTarget *iface, + const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode, + ID2D1GradientStopCollection **gradient) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n", + iface, stops, stop_count, gamma, extend_mode, gradient); + + return ID2D1RenderTarget_CreateGradientStopCollection(render_target->dxgi_target, + stops, stop_count, gamma, extend_mode, gradient); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateLinearGradientBrush(ID2D1HwndRenderTarget *iface, + const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1GradientStopCollection *gradient, ID2D1LinearGradientBrush **brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n", + iface, gradient_brush_desc, brush_desc, gradient, brush); + + return ID2D1RenderTarget_CreateLinearGradientBrush(render_target->dxgi_target, + gradient_brush_desc, brush_desc, gradient, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateRadialGradientBrush(ID2D1HwndRenderTarget *iface, + const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1GradientStopCollection *gradient, ID2D1RadialGradientBrush **brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n", + iface, gradient_brush_desc, brush_desc, gradient, brush); + + return ID2D1RenderTarget_CreateRadialGradientBrush(render_target->dxgi_target, + gradient_brush_desc, brush_desc, gradient, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateCompatibleRenderTarget(ID2D1HwndRenderTarget *iface, + const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **render_target) +{ + struct d2d_hwnd_render_target *rt = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p,\n", + iface, size, pixel_size, format, options, render_target); + + return ID2D1RenderTarget_CreateCompatibleRenderTarget(rt->dxgi_target, + size, pixel_size, format, options, render_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateLayer(ID2D1HwndRenderTarget *iface, + const D2D1_SIZE_F *size, ID2D1Layer **layer) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, size %p, layer %p.\n", iface, size, layer); + + return ID2D1RenderTarget_CreateLayer(render_target->dxgi_target, size, layer); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_CreateMesh(ID2D1HwndRenderTarget *iface, ID2D1Mesh **mesh) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, mesh %p.\n", iface, mesh); + + return ID2D1RenderTarget_CreateMesh(render_target->dxgi_target, mesh); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawLine(ID2D1HwndRenderTarget *iface, + D2D1_POINT_2F p0, D2D1_POINT_2F p1, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, p0 {%.8e, %.8e}, p1 {%.8e, %.8e}, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, p0.x, p0.y, p1.x, p1.y, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawLine(render_target->dxgi_target, p0, p1, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawRectangle(ID2D1HwndRenderTarget *iface, + const D2D1_RECT_F *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, rect, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawRectangle(render_target->dxgi_target, rect, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillRectangle(ID2D1HwndRenderTarget *iface, + const D2D1_RECT_F *rect, ID2D1Brush *brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p.\n", iface, rect, brush); + + ID2D1RenderTarget_FillRectangle(render_target->dxgi_target, rect, brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawRoundedRectangle(ID2D1HwndRenderTarget *iface, + const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, rect, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawRoundedRectangle(render_target->dxgi_target, rect, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillRoundedRectangle(ID2D1HwndRenderTarget *iface, + const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p.\n", iface, rect, brush); + + ID2D1RenderTarget_FillRoundedRectangle(render_target->dxgi_target, rect, brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawEllipse(ID2D1HwndRenderTarget *iface, + const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, ellipse %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, ellipse, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawEllipse(render_target->dxgi_target, ellipse, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillEllipse(ID2D1HwndRenderTarget *iface, + const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, ellipse %p, brush %p.\n", iface, ellipse, brush); + + ID2D1RenderTarget_FillEllipse(render_target->dxgi_target, ellipse, brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawGeometry(ID2D1HwndRenderTarget *iface, + ID2D1Geometry *geometry, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, geometry %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, geometry, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawGeometry(render_target->dxgi_target, geometry, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillGeometry(ID2D1HwndRenderTarget *iface, + ID2D1Geometry *geometry, ID2D1Brush *brush, ID2D1Brush *opacity_brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, geometry %p, brush %p, opacity_brush %p.\n", iface, geometry, brush, opacity_brush); + + ID2D1RenderTarget_FillGeometry(render_target->dxgi_target, geometry, brush, opacity_brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillMesh(ID2D1HwndRenderTarget *iface, + ID2D1Mesh *mesh, ID2D1Brush *brush) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, mesh %p, brush %p.\n", iface, mesh, brush); + + ID2D1RenderTarget_FillMesh(render_target->dxgi_target, mesh, brush); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_FillOpacityMask(ID2D1HwndRenderTarget *iface, + ID2D1Bitmap *mask, ID2D1Brush *brush, D2D1_OPACITY_MASK_CONTENT content, + const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, mask %p, brush %p, content %#x, dst_rect %p, src_rect %p.\n", + iface, mask, brush, content, dst_rect, src_rect); + + ID2D1RenderTarget_FillOpacityMask(render_target->dxgi_target, + mask, brush, content, dst_rect, src_rect); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawBitmap(ID2D1HwndRenderTarget *iface, + ID2D1Bitmap *bitmap, const D2D1_RECT_F *dst_rect, float opacity, + D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, const D2D1_RECT_F *src_rect) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, bitmap %p, dst_rect %p, opacity %.8e, interpolation_mode %#x, src_rect %p.\n", + iface, bitmap, dst_rect, opacity, interpolation_mode, src_rect); + + ID2D1RenderTarget_DrawBitmap(render_target->dxgi_target, + bitmap, dst_rect, opacity, interpolation_mode, src_rect); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawText(ID2D1HwndRenderTarget *iface, + const WCHAR *string, UINT32 string_len, IDWriteTextFormat *text_format, const D2D1_RECT_F *layout_rect, + ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuring_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, string %s, string_len %u, text_format %p, layout_rect %p, " + "brush %p, options %#x, measuring_mode %#x.\n", + iface, debugstr_wn(string, string_len), string_len, text_format, layout_rect, + brush, options, measuring_mode); + + ID2D1RenderTarget_DrawText(render_target->dxgi_target, string, string_len, + text_format, layout_rect, brush, options, measuring_mode); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawTextLayout(ID2D1HwndRenderTarget *iface, + D2D1_POINT_2F origin, IDWriteTextLayout *layout, ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, origin {%.8e, %.8e}, layout %p, brush %p, options %#x.\n", + iface, origin.x, origin.y, layout, brush, options); + + ID2D1RenderTarget_DrawTextLayout(render_target->dxgi_target, origin, layout, brush, options); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_DrawGlyphRun(ID2D1HwndRenderTarget *iface, + D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush, + DWRITE_MEASURING_MODE measuring_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, baseline_origin {%.8e, %.8e}, glyph_run %p, brush %p, measuring_mode %#x.\n", + iface, baseline_origin.x, baseline_origin.y, glyph_run, brush, measuring_mode); + + ID2D1RenderTarget_DrawGlyphRun(render_target->dxgi_target, + baseline_origin, glyph_run, brush, measuring_mode); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetTransform(ID2D1HwndRenderTarget *iface, + const D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, transform %p.\n", iface, transform); + + ID2D1RenderTarget_SetTransform(render_target->dxgi_target, transform); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetTransform(ID2D1HwndRenderTarget *iface, + D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, transform %p.\n", iface, transform); + + ID2D1RenderTarget_GetTransform(render_target->dxgi_target, transform); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetAntialiasMode(ID2D1HwndRenderTarget *iface, + D2D1_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, antialias_mode %#x.\n", iface, antialias_mode); + + ID2D1RenderTarget_SetAntialiasMode(render_target->dxgi_target, antialias_mode); +} + +static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_hwnd_render_target_GetAntialiasMode(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetAntialiasMode(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetTextAntialiasMode(ID2D1HwndRenderTarget *iface, + D2D1_TEXT_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, antialias_mode %#x.\n", iface, antialias_mode); + + ID2D1RenderTarget_SetTextAntialiasMode(render_target->dxgi_target, antialias_mode); +} + +static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_hwnd_render_target_GetTextAntialiasMode( + ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetTextAntialiasMode(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetTextRenderingParams(ID2D1HwndRenderTarget *iface, + IDWriteRenderingParams *text_rendering_params) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params); + + ID2D1RenderTarget_SetTextRenderingParams(render_target->dxgi_target, text_rendering_params); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetTextRenderingParams(ID2D1HwndRenderTarget *iface, + IDWriteRenderingParams **text_rendering_params) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params); + + ID2D1RenderTarget_GetTextRenderingParams(render_target->dxgi_target, text_rendering_params); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetTags(ID2D1HwndRenderTarget *iface, D2D1_TAG tag1, D2D1_TAG tag2) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, tag1 %s, tag2 %s.\n", iface, wine_dbgstr_longlong(tag1), wine_dbgstr_longlong(tag2)); + + ID2D1RenderTarget_SetTags(render_target->dxgi_target, tag1, tag2); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetTags(ID2D1HwndRenderTarget *iface, D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + ID2D1RenderTarget_GetTags(render_target->dxgi_target, tag1, tag2); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_PushLayer(ID2D1HwndRenderTarget *iface, + const D2D1_LAYER_PARAMETERS *layer_parameters, ID2D1Layer *layer) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, layer_parameters %p, layer %p.\n", iface, layer_parameters, layer); + + ID2D1RenderTarget_PushLayer(render_target->dxgi_target, layer_parameters, layer); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_PopLayer(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_PopLayer(render_target->dxgi_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_Flush(ID2D1HwndRenderTarget *iface, D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + HRESULT hr; + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + hr = ID2D1RenderTarget_Flush(render_target->dxgi_target, tag1, tag2); + render_target_present(render_target); + + return hr; +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SaveDrawingState(ID2D1HwndRenderTarget *iface, + ID2D1DrawingStateBlock *state_block) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, state_block %p.\n", iface, state_block); + + ID2D1RenderTarget_SaveDrawingState(render_target->dxgi_target, state_block); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_RestoreDrawingState(ID2D1HwndRenderTarget *iface, + ID2D1DrawingStateBlock *state_block) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, state_block %p.\n", iface, state_block); + + ID2D1RenderTarget_RestoreDrawingState(render_target->dxgi_target, state_block); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_PushAxisAlignedClip(ID2D1HwndRenderTarget *iface, + const D2D1_RECT_F *clip_rect, D2D1_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, clip_rect %p, antialias_mode %#x.\n", iface, clip_rect, antialias_mode); + + ID2D1RenderTarget_PushAxisAlignedClip(render_target->dxgi_target, clip_rect, antialias_mode); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_PopAxisAlignedClip(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_PopAxisAlignedClip(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_Clear(ID2D1HwndRenderTarget *iface, const D2D1_COLOR_F *color) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, color %p.\n", iface, color); + + ID2D1RenderTarget_Clear(render_target->dxgi_target, color); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_BeginDraw(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_BeginDraw(render_target->dxgi_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_EndDraw(ID2D1HwndRenderTarget *iface, + D2D1_TAG *tag1, D2D1_TAG *tag2) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + HRESULT hr; + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + hr = ID2D1RenderTarget_EndDraw(render_target->dxgi_target, tag1, tag2); + render_target_present(render_target); + + return hr; +} + +static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_hwnd_render_target_GetPixelFormat(ID2D1HwndRenderTarget *iface, + D2D1_PIXEL_FORMAT *format) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, format %p.\n", iface, format); + + *format = ID2D1RenderTarget_GetPixelFormat(render_target->dxgi_target); + return format; +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_SetDpi(ID2D1HwndRenderTarget *iface, float dpi_x, float dpi_y) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, dpi_x %.8e, dpi_y %.8e.\n", iface, dpi_x, dpi_y); + + ID2D1RenderTarget_SetDpi(render_target->dxgi_target, dpi_x, dpi_y); +} + +static void STDMETHODCALLTYPE d2d_hwnd_render_target_GetDpi(ID2D1HwndRenderTarget *iface, float *dpi_x, float *dpi_y) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y); + + ID2D1RenderTarget_GetDpi(render_target->dxgi_target, dpi_x, dpi_y); +} + +static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_hwnd_render_target_GetSize(ID2D1HwndRenderTarget *iface, D2D1_SIZE_F *size) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, size %p.\n", iface, size); + + *size = ID2D1RenderTarget_GetSize(render_target->dxgi_target); + return size; +} + +static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_hwnd_render_target_GetPixelSize(ID2D1HwndRenderTarget *iface, + D2D1_SIZE_U *pixel_size) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, pixel_size %p.\n", iface, pixel_size); + + *pixel_size = ID2D1RenderTarget_GetPixelSize(render_target->dxgi_target); + return pixel_size; +} + +static UINT32 STDMETHODCALLTYPE d2d_hwnd_render_target_GetMaximumBitmapSize(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetMaximumBitmapSize(render_target->dxgi_target); +} + +static BOOL STDMETHODCALLTYPE d2d_hwnd_render_target_IsSupported(ID2D1HwndRenderTarget *iface, + const D2D1_RENDER_TARGET_PROPERTIES *desc) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + return ID2D1RenderTarget_IsSupported(render_target->dxgi_target, desc); +} + +static D2D1_WINDOW_STATE STDMETHODCALLTYPE d2d_hwnd_render_target_CheckWindowState(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return IDXGISwapChain_Present(render_target->swapchain, render_target->sync_interval, DXGI_PRESENT_TEST) == + DXGI_STATUS_OCCLUDED ? D2D1_WINDOW_STATE_OCCLUDED : D2D1_WINDOW_STATE_NONE; +} + +static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_Resize(ID2D1HwndRenderTarget *iface, const D2D1_SIZE_U size) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + IDXGISurface1 *dxgi_surface; + HRESULT hr; + + TRACE("iface %p, width %u, height %u.\n", iface, size.width, size.height); + + d2d_d3d_render_target_create_rtv(render_target->dxgi_target, NULL); + + if (SUCCEEDED(hr = IDXGISwapChain_ResizeBuffers(render_target->swapchain, 1, size.width, size.height, + DXGI_FORMAT_UNKNOWN, 0))) + { + if (FAILED(hr = IDXGISwapChain_GetBuffer(render_target->swapchain, 0, &IID_IDXGISurface1, + (void **)&dxgi_surface))) + { + WARN("Failed to get buffer, hr %#x.\n", hr); + return hr; + } + + hr = d2d_d3d_render_target_create_rtv(render_target->dxgi_target, dxgi_surface); + IDXGISurface1_Release(dxgi_surface); + } + + return hr; +} + +static HWND STDMETHODCALLTYPE d2d_hwnd_render_target_GetHwnd(ID2D1HwndRenderTarget *iface) +{ + struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return render_target->hwnd; +} + +static const struct ID2D1HwndRenderTargetVtbl d2d_hwnd_render_target_vtbl = +{ + d2d_hwnd_render_target_QueryInterface, + d2d_hwnd_render_target_AddRef, + d2d_hwnd_render_target_Release, + d2d_hwnd_render_target_GetFactory, + d2d_hwnd_render_target_CreateBitmap, + d2d_hwnd_render_target_CreateBitmapFromWicBitmap, + d2d_hwnd_render_target_CreateSharedBitmap, + d2d_hwnd_render_target_CreateBitmapBrush, + d2d_hwnd_render_target_CreateSolidColorBrush, + d2d_hwnd_render_target_CreateGradientStopCollection, + d2d_hwnd_render_target_CreateLinearGradientBrush, + d2d_hwnd_render_target_CreateRadialGradientBrush, + d2d_hwnd_render_target_CreateCompatibleRenderTarget, + d2d_hwnd_render_target_CreateLayer, + d2d_hwnd_render_target_CreateMesh, + d2d_hwnd_render_target_DrawLine, + d2d_hwnd_render_target_DrawRectangle, + d2d_hwnd_render_target_FillRectangle, + d2d_hwnd_render_target_DrawRoundedRectangle, + d2d_hwnd_render_target_FillRoundedRectangle, + d2d_hwnd_render_target_DrawEllipse, + d2d_hwnd_render_target_FillEllipse, + d2d_hwnd_render_target_DrawGeometry, + d2d_hwnd_render_target_FillGeometry, + d2d_hwnd_render_target_FillMesh, + d2d_hwnd_render_target_FillOpacityMask, + d2d_hwnd_render_target_DrawBitmap, + d2d_hwnd_render_target_DrawText, + d2d_hwnd_render_target_DrawTextLayout, + d2d_hwnd_render_target_DrawGlyphRun, + d2d_hwnd_render_target_SetTransform, + d2d_hwnd_render_target_GetTransform, + d2d_hwnd_render_target_SetAntialiasMode, + d2d_hwnd_render_target_GetAntialiasMode, + d2d_hwnd_render_target_SetTextAntialiasMode, + d2d_hwnd_render_target_GetTextAntialiasMode, + d2d_hwnd_render_target_SetTextRenderingParams, + d2d_hwnd_render_target_GetTextRenderingParams, + d2d_hwnd_render_target_SetTags, + d2d_hwnd_render_target_GetTags, + d2d_hwnd_render_target_PushLayer, + d2d_hwnd_render_target_PopLayer, + d2d_hwnd_render_target_Flush, + d2d_hwnd_render_target_SaveDrawingState, + d2d_hwnd_render_target_RestoreDrawingState, + d2d_hwnd_render_target_PushAxisAlignedClip, + d2d_hwnd_render_target_PopAxisAlignedClip, + d2d_hwnd_render_target_Clear, + d2d_hwnd_render_target_BeginDraw, + d2d_hwnd_render_target_EndDraw, + d2d_hwnd_render_target_GetPixelFormat, + d2d_hwnd_render_target_SetDpi, + d2d_hwnd_render_target_GetDpi, + d2d_hwnd_render_target_GetSize, + d2d_hwnd_render_target_GetPixelSize, + d2d_hwnd_render_target_GetMaximumBitmapSize, + d2d_hwnd_render_target_IsSupported, + d2d_hwnd_render_target_CheckWindowState, + d2d_hwnd_render_target_Resize, + d2d_hwnd_render_target_GetHwnd +}; + +HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target, ID2D1Factory *factory, + ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc, + const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_rt_desc) +{ + D2D1_RENDER_TARGET_PROPERTIES dxgi_rt_desc; + DXGI_SWAP_CHAIN_DESC swapchain_desc; + IDXGIAdapter *dxgi_adapter; + IDXGIFactory *dxgi_factory; + IDXGISurface *dxgi_surface; + IDXGIDevice *dxgi_device; + HRESULT hr; + + if (!IsWindow(hwnd_rt_desc->hwnd)) + return HRESULT_FROM_WIN32(ERROR_INVALID_WINDOW_HANDLE); + + render_target->ID2D1HwndRenderTarget_iface.lpVtbl = &d2d_hwnd_render_target_vtbl; + render_target->refcount = 1; + render_target->hwnd = hwnd_rt_desc->hwnd; + render_target->sync_interval = hwnd_rt_desc->presentOptions & D2D1_PRESENT_OPTIONS_IMMEDIATELY ? 0 : 1; + + if (FAILED(hr = ID3D10Device1_QueryInterface(device, &IID_IDXGIDevice, (void **)&dxgi_device))) + { + WARN("Failed to get IDXGIDevice interface, hr %#x.\n", hr); + return hr; + } + + hr = IDXGIDevice_GetAdapter(dxgi_device, &dxgi_adapter); + IDXGIDevice_Release(dxgi_device); + if (FAILED(hr)) + { + WARN("Failed to get IDXGIAdapter interface, hr %#x.\n", hr); + return hr; + } + + hr = IDXGIAdapter_GetParent(dxgi_adapter, &IID_IDXGIFactory, (void **)&dxgi_factory); + IDXGIAdapter_Release(dxgi_adapter); + if (FAILED(hr)) + { + WARN("Failed to get IDXGIFactory interface, hr %#x.\n", hr); + return hr; + } + + dxgi_rt_desc = *desc; + if (dxgi_rt_desc.dpiX == 0.0f && dxgi_rt_desc.dpiY == 0.0f) + ID2D1Factory_GetDesktopDpi(factory, &dxgi_rt_desc.dpiX, &dxgi_rt_desc.dpiY); + + if (dxgi_rt_desc.pixelFormat.format == DXGI_FORMAT_UNKNOWN) + { + dxgi_rt_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + dxgi_rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE; + } + + swapchain_desc.BufferDesc.Width = hwnd_rt_desc->pixelSize.width; + swapchain_desc.BufferDesc.Height = hwnd_rt_desc->pixelSize.height; + swapchain_desc.BufferDesc.RefreshRate.Numerator = 60; + swapchain_desc.BufferDesc.RefreshRate.Denominator = 1; + swapchain_desc.BufferDesc.Format = dxgi_rt_desc.pixelFormat.format; + swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + swapchain_desc.SampleDesc.Count = 1; + swapchain_desc.SampleDesc.Quality = 0; + swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapchain_desc.BufferCount = 1; + swapchain_desc.OutputWindow = hwnd_rt_desc->hwnd; + swapchain_desc.Windowed = TRUE; + swapchain_desc.SwapEffect = hwnd_rt_desc->presentOptions & D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS ? + DXGI_SWAP_EFFECT_SEQUENTIAL : DXGI_SWAP_EFFECT_DISCARD; + swapchain_desc.Flags = 0; + + hr = IDXGIFactory_CreateSwapChain(dxgi_factory, (IUnknown *)device, &swapchain_desc, &render_target->swapchain); + IDXGIFactory_Release(dxgi_factory); + if (FAILED(hr)) + { + WARN("Failed to create a swapchain, hr %#x.\n", hr); + return hr; + } + + if (FAILED(hr = IDXGISwapChain_GetBuffer(render_target->swapchain, 0, &IID_IDXGISurface, (void **)&dxgi_surface))) + { + WARN("Failed to get buffer, hr %#x.\n", hr); + IDXGISwapChain_Release(render_target->swapchain); + return hr; + } + + hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, dxgi_surface, &dxgi_rt_desc, &render_target->dxgi_target); + IDXGISurface_Release(dxgi_surface); + if (FAILED(hr)) + { + WARN("Failed to create DXGI surface render target, hr %#x.\n", hr); + IDXGISwapChain_Release(render_target->swapchain); + return hr; + } + + return S_OK; +} diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index 6824e9f..e9a971e 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -2181,7 +2181,7 @@ err: return hr; } -HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *iface, IDXGISurface1 *surface) +HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *iface, IDXGISurface1 *surface) { struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface); DXGI_SURFACE_DESC surface_desc; @@ -2189,6 +2189,13 @@ HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *iface, IDXGISurf ID3D10Resource *resource; HRESULT hr; + if (!surface) + { + ID3D10RenderTargetView_Release(render_target->view); + render_target->view = NULL; + return S_OK; + } + if (FAILED(hr = IDXGISurface1_GetDesc(surface, &surface_desc))) { WARN("Failed to get surface desc, hr %#x.\n", hr); diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 91d5136..c9e1692 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -2831,6 +2831,56 @@ static void test_dc_target(void) ID2D1Factory_Release(factory); } +static void test_hwnd_target(void) +{ + D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc; + D2D1_RENDER_TARGET_PROPERTIES desc; + ID2D1HwndRenderTarget *rt; + ID2D1Factory *factory; + ID3D10Device1 *device; + HRESULT hr; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + ID3D10Device1_Release(device); + + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); + ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr); + + desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + desc.dpiX = 0.0f; + desc.dpiY = 0.0f; + desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + hwnd_rt_desc.hwnd = NULL; + hwnd_rt_desc.pixelSize.width = 64; + hwnd_rt_desc.pixelSize.height = 64; + hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE; + + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + ok(FAILED(hr), "Target creation should fail, hr %#x.\n", hr); + + hwnd_rt_desc.hwnd = (HWND)0xdeadbeef; + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + ok(FAILED(hr), "Target creation should fail, hr %#x.\n", hr); + + hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0); + ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n"); + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + ID2D1HwndRenderTarget_Release(rt); + + DestroyWindow(hwnd_rt_desc.hwnd); + ID2D1Factory_Release(factory); +} + START_TEST(d2d1) { test_clip(); @@ -2846,4 +2896,5 @@ START_TEST(d2d1) test_create_target(); test_draw_text_layout(); test_dc_target(); + test_hwnd_target(); } -- 2.9.3 From mbruni at codeweavers.com Mon Oct 3 16:46:51 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Mon, 3 Oct 2016 23:46:51 +0200 Subject: [PATCH resend 1/6] wined3d: Add ARB_fragment_coord_conventions extension. Message-ID: <1475531216-20874-1-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- dlls/wined3d/directx.c | 2 ++ dlls/wined3d/wined3d_gl.h | 1 + 2 files changed, 3 insertions(+) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 50083d1..00e8d63 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -120,6 +120,7 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_ARB_draw_instanced", ARB_DRAW_INSTANCED }, {"GL_ARB_ES2_compatibility", ARB_ES2_COMPATIBILITY }, {"GL_ARB_explicit_attrib_location", ARB_EXPLICIT_ATTRIB_LOCATION }, + {"GL_ARB_fragment_coord_conventions", ARB_FRAGMENT_COORD_CONVENTIONS}, {"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM }, {"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER }, {"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT }, @@ -3556,6 +3557,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD /* ARB_geometry_shader4 exposes a somewhat different API compared to 3.2 * core geometry shaders so it's not really correct to expose the * extension for core-only support. */ + {ARB_FRAGMENT_COORD_CONVENTIONS, MAKEDWORD_VERSION(3, 2)}, {ARB_PROVOKING_VERTEX, MAKEDWORD_VERSION(3, 2)}, {ARB_SYNC, MAKEDWORD_VERSION(3, 2)}, {ARB_VERTEX_ARRAY_BGRA, MAKEDWORD_VERSION(3, 2)}, diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index 67ab6f7..3757b02 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -55,6 +55,7 @@ enum wined3d_gl_extension ARB_DRAW_INSTANCED, ARB_ES2_COMPATIBILITY, ARB_EXPLICIT_ATTRIB_LOCATION, + ARB_FRAGMENT_COORD_CONVENTIONS, ARB_FRAGMENT_PROGRAM, ARB_FRAGMENT_SHADER, ARB_FRAMEBUFFER_OBJECT, -- 2.7.3 From mbruni at codeweavers.com Mon Oct 3 16:46:52 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Mon, 3 Oct 2016 23:46:52 +0200 Subject: [PATCH v2 2/6] wined3d: Avoid vpos fixups when ARB_fragment_coord_conventions is supported. In-Reply-To: <1475531216-20874-1-git-send-email-mbruni@codeweavers.com> References: <1475531216-20874-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1475531216-20874-2-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- v2: Fix for disabled AlwaysOffscreen / backbuffer ORM. dlls/wined3d/context.c | 2 ++ dlls/wined3d/glsl_shader.c | 26 ++++++++++++++++++++++---- dlls/wined3d/shader.c | 2 ++ dlls/wined3d/wined3d_private.h | 3 ++- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index e09c6fd..8c08310 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -2418,6 +2418,8 @@ static void context_set_render_offscreen(struct wined3d_context *context, BOOL o context_invalidate_state(context, STATE_VIEWPORT); context_invalidate_state(context, STATE_SCISSORRECT); context_invalidate_state(context, STATE_FRONTFACE); + if (context->gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) + context_invalidate_state(context, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); context->render_offscreen = offscreen; } diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 55cbdcf..72740af 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -2194,9 +2194,23 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont } if (reg_maps->vpos || reg_maps->usesdsy) { - ++extra_constants_needed; - shader_addline(buffer, "uniform vec4 ycorrection;\n"); - shader_addline(buffer, "vec4 vpos;\n"); + if (reg_maps->usesdsy || !gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) + { + ++extra_constants_needed; + shader_addline(buffer, "uniform vec4 ycorrection;\n"); + } + if (reg_maps->vpos) + { + if (gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) + { + if (shader->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) + shader_addline(buffer, "layout(%spixel_center_integer) in vec4 gl_FragCoord;\n", + ps_args->render_offscreen ? "" : "origin_upper_left, "); + else if (!ps_args->render_offscreen) + shader_addline(buffer, "layout(origin_upper_left) in vec4 gl_FragCoord;\n"); + } + shader_addline(buffer, "vec4 vpos;\n"); + } } if (ps_args->alpha_test_func + 1 != WINED3D_CMP_ALWAYS) @@ -5899,6 +5913,8 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context shader_glsl_enable_extensions(buffer, gl_info); if (gl_info->supported[ARB_DERIVATIVE_CONTROL]) shader_addline(buffer, "#extension GL_ARB_derivative_control : enable\n"); + if (gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) + shader_addline(buffer, "#extension GL_ARB_fragment_coord_conventions : enable\n"); if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n"); /* The spec says that it doesn't have to be explicitly enabled, but the @@ -5929,7 +5945,9 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context * on drivers that returns integer values. */ if (reg_maps->vpos) { - if (shader->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) + if (gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) + shader_addline(buffer, "vpos = gl_FragCoord;\n"); + else if (shader->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) shader_addline(buffer, "vpos = floor(vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1));\n"); else diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 1c48589..594520c 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -3279,6 +3279,8 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 if (d3d_info->emulated_flatshading) args->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; + + args->render_offscreen = gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS] ? context->render_offscreen : 0; } static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index a968bda..851c914 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1107,7 +1107,8 @@ struct ps_compile_args { DWORD pointsprite : 1; DWORD flatshading : 1; DWORD alpha_test_func : 3; - DWORD padding : 27; + DWORD render_offscreen : 1; + DWORD padding : 26; }; enum fog_src_type { -- 2.7.3 From mbruni at codeweavers.com Mon Oct 3 16:46:53 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Mon, 3 Oct 2016 23:46:53 +0200 Subject: [PATCH 3/6] wined3d: Add core version of the functions introduced by EXT_draw_buffers2. In-Reply-To: <1475531216-20874-1-git-send-email-mbruni@codeweavers.com> References: <1475531216-20874-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1475531216-20874-3-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- dlls/wined3d/directx.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 00e8d63..d658692 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -3056,10 +3056,12 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glDeleteShader) /* OpenGL 2.0 */ USE_GL_FUNC(glDeleteVertexArrays) /* OpenGL 3.0 */ USE_GL_FUNC(glDetachShader) /* OpenGL 2.0 */ + USE_GL_FUNC(glDisablei) /* OpenGL 3.0 */ USE_GL_FUNC(glDisableVertexAttribArray) /* OpenGL 2.0 */ USE_GL_FUNC(glDrawArraysInstanced) /* OpenGL 3.1 */ USE_GL_FUNC(glDrawBuffers) /* OpenGL 2.0 */ USE_GL_FUNC(glDrawElementsInstanced) /* OpenGL 3.1 */ + USE_GL_FUNC(glEnablei) /* OpenGL 3.0 */ USE_GL_FUNC(glEnableVertexAttribArray) /* OpenGL 2.0 */ USE_GL_FUNC(glEndQuery) /* OpenGL 1.5 */ USE_GL_FUNC(glGenBuffers) /* OpenGL 1.5 */ @@ -3068,9 +3070,11 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glGetActiveUniform) /* OpenGL 2.0 */ USE_GL_FUNC(glGetAttachedShaders) /* OpenGL 2.0 */ USE_GL_FUNC(glGetAttribLocation) /* OpenGL 2.0 */ + USE_GL_FUNC(glGetBooleani_v) /* OpenGL 3.0 */ USE_GL_FUNC(glGetBufferSubData) /* OpenGL 1.5 */ USE_GL_FUNC(glGetCompressedTexImage) /* OpenGL 1.3 */ USE_GL_FUNC(glGetDebugMessageLog) /* OpenGL 4.3 */ + USE_GL_FUNC(glGetIntegeri_v) /* OpenGL 3.0 */ USE_GL_FUNC(glGetProgramInfoLog) /* OpenGL 2.0 */ USE_GL_FUNC(glGetProgramiv) /* OpenGL 2.0 */ USE_GL_FUNC(glGetQueryiv) /* OpenGL 1.5 */ @@ -3082,6 +3086,7 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glGetUniformfv) /* OpenGL 2.0 */ USE_GL_FUNC(glGetUniformiv) /* OpenGL 2.0 */ USE_GL_FUNC(glGetUniformLocation) /* OpenGL 2.0 */ + USE_GL_FUNC(glIsEnabledi) /* OpenGL 3.0 */ USE_GL_FUNC(glLinkProgram) /* OpenGL 2.0 */ USE_GL_FUNC(glMapBuffer) /* OpenGL 1.5 */ USE_GL_FUNC(glPointParameteri) /* OpenGL 1.4 */ @@ -3178,10 +3183,12 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) MAP_GL_FUNCTION(glDeleteQueries, glDeleteQueriesARB); MAP_GL_FUNCTION(glDeleteShader, glDeleteObjectARB); MAP_GL_FUNCTION(glDetachShader, glDetachObjectARB); + MAP_GL_FUNCTION(glDisablei, glDisableIndexedEXT); MAP_GL_FUNCTION(glDisableVertexAttribArray, glDisableVertexAttribArrayARB); MAP_GL_FUNCTION(glDrawArraysInstanced, glDrawArraysInstancedARB); MAP_GL_FUNCTION(glDrawBuffers, glDrawBuffersARB); MAP_GL_FUNCTION(glDrawElementsInstanced, glDrawElementsInstancedARB); + MAP_GL_FUNCTION(glEnablei, glEnableIndexedEXT); MAP_GL_FUNCTION(glEnableVertexAttribArray, glEnableVertexAttribArrayARB); MAP_GL_FUNCTION(glEndQuery, glEndQueryARB); MAP_GL_FUNCTION(glGenBuffers, glGenBuffersARB); @@ -3189,9 +3196,11 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) MAP_GL_FUNCTION(glGetActiveUniform, glGetActiveUniformARB); MAP_GL_FUNCTION(glGetAttachedShaders, glGetAttachedObjectsARB); MAP_GL_FUNCTION(glGetAttribLocation, glGetAttribLocationARB); + MAP_GL_FUNCTION(glGetBooleani_v, glGetBooleanIndexedvEXT); MAP_GL_FUNCTION(glGetBufferSubData, glGetBufferSubDataARB); MAP_GL_FUNCTION(glGetCompressedTexImage, glGetCompressedTexImageARB); MAP_GL_FUNCTION(glGetDebugMessageLog, glGetDebugMessageLogARB); + MAP_GL_FUNCTION(glGetIntegeri_v, glGetIntegerIndexedvEXT); MAP_GL_FUNCTION(glGetProgramInfoLog, glGetInfoLogARB); MAP_GL_FUNCTION(glGetProgramiv, glGetObjectParameterivARB); MAP_GL_FUNCTION(glGetQueryiv, glGetQueryivARB); @@ -3202,6 +3211,7 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) MAP_GL_FUNCTION(glGetUniformfv, glGetUniformfvARB); MAP_GL_FUNCTION(glGetUniformiv, glGetUniformivARB); MAP_GL_FUNCTION(glGetUniformLocation, glGetUniformLocationARB); + MAP_GL_FUNCTION(glIsEnabledi, glIsEnabledIndexedEXT); MAP_GL_FUNCTION(glLinkProgram, glLinkProgramARB); MAP_GL_FUNCTION(glMapBuffer, glMapBufferARB); MAP_GL_FUNCTION_CAST(glShaderSource, glShaderSourceARB); -- 2.7.3 From mbruni at codeweavers.com Mon Oct 3 16:46:54 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Mon, 3 Oct 2016 23:46:54 +0200 Subject: [PATCH 4/6] wined3d: Add ARB_viewport_array extension. In-Reply-To: <1475531216-20874-1-git-send-email-mbruni@codeweavers.com> References: <1475531216-20874-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1475531216-20874-4-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- dlls/wined3d/directx.c | 13 +++++++++++++ dlls/wined3d/wined3d_gl.h | 1 + 2 files changed, 14 insertions(+) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index d658692..b4394b8 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -172,6 +172,7 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM }, {"GL_ARB_vertex_shader", ARB_VERTEX_SHADER }, {"GL_ARB_vertex_type_2_10_10_10_rev", ARB_VERTEX_TYPE_2_10_10_10_REV}, + {"GL_ARB_viewport_array", ARB_VIEWPORT_ARRAY }, /* ATI */ {"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER }, @@ -2829,6 +2830,17 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glVertexAttrib4uivARB) USE_GL_FUNC(glVertexAttrib4usvARB) USE_GL_FUNC(glVertexAttribPointerARB) + /* GL_ARB_viewport_array */ + USE_GL_FUNC(glDepthRangeArrayv) + USE_GL_FUNC(glDepthRangeIndexed) + USE_GL_FUNC(glGetDoublei_v) + USE_GL_FUNC(glGetFloati_v) + USE_GL_FUNC(glScissorArrayv) + USE_GL_FUNC(glScissorIndexed) + USE_GL_FUNC(glScissorIndexedv) + USE_GL_FUNC(glViewportArrayv) + USE_GL_FUNC(glViewportIndexedf) + USE_GL_FUNC(glViewportIndexedfv) /* GL_ATI_fragment_shader */ USE_GL_FUNC(glAlphaFragmentOp1ATI) USE_GL_FUNC(glAlphaFragmentOp2ATI) @@ -3583,6 +3595,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD {ARB_VERTEX_TYPE_2_10_10_10_REV, MAKEDWORD_VERSION(3, 3)}, {ARB_ES2_COMPATIBILITY, MAKEDWORD_VERSION(4, 1)}, + {ARB_VIEWPORT_ARRAY, MAKEDWORD_VERSION(4, 1)}, {ARB_INTERNALFORMAT_QUERY, MAKEDWORD_VERSION(4, 2)}, {ARB_MAP_BUFFER_ALIGNMENT, MAKEDWORD_VERSION(4, 2)}, diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index 3757b02..57fbea4 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -107,6 +107,7 @@ enum wined3d_gl_extension ARB_VERTEX_PROGRAM, ARB_VERTEX_SHADER, ARB_VERTEX_TYPE_2_10_10_10_REV, + ARB_VIEWPORT_ARRAY, /* ATI */ ATI_FRAGMENT_SHADER, ATI_SEPARATE_STENCIL, -- 2.7.3 From mbruni at codeweavers.com Mon Oct 3 16:46:55 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Mon, 3 Oct 2016 23:46:55 +0200 Subject: [PATCH 5/6] wined3d: Add ARB_clip_control extension. In-Reply-To: <1475531216-20874-1-git-send-email-mbruni@codeweavers.com> References: <1475531216-20874-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1475531216-20874-5-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- dlls/wined3d/directx.c | 4 ++++ dlls/wined3d/wined3d_gl.h | 1 + 2 files changed, 5 insertions(+) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index b4394b8..b03ddf6 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -109,6 +109,7 @@ static const struct wined3d_extension_map gl_extension_map[] = /* ARB */ {"GL_ARB_blend_func_extended", ARB_BLEND_FUNC_EXTENDED }, + {"GL_ARB_clip_control", ARB_CLIP_CONTROL }, {"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT }, {"GL_ARB_copy_buffer", ARB_COPY_BUFFER }, {"GL_ARB_debug_output", ARB_DEBUG_OUTPUT }, @@ -2580,6 +2581,8 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) /* GL_ARB_blend_func_extended */ USE_GL_FUNC(glBindFragDataLocationIndexed) USE_GL_FUNC(glGetFragDataIndex) + /* GL_ARB_clip_control */ + USE_GL_FUNC(glClipControl) /* GL_ARB_color_buffer_float */ USE_GL_FUNC(glClampColorARB) /* GL_ARB_copy_buffer */ @@ -3607,6 +3610,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD {ARB_TEXTURE_QUERY_LEVELS, MAKEDWORD_VERSION(4, 3)}, {ARB_TEXTURE_VIEW, MAKEDWORD_VERSION(4, 3)}, + {ARB_CLIP_CONTROL, MAKEDWORD_VERSION(4, 5)}, {ARB_DERIVATIVE_CONTROL, MAKEDWORD_VERSION(4, 5)}, }; struct wined3d_driver_info *driver_info = &adapter->driver_info; diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index 57fbea4..b71190d 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -44,6 +44,7 @@ enum wined3d_gl_extension APPLE_YCBCR_422, /* ARB */ ARB_BLEND_FUNC_EXTENDED, + ARB_CLIP_CONTROL, ARB_COLOR_BUFFER_FLOAT, ARB_COPY_BUFFER, ARB_DEBUG_OUTPUT, -- 2.7.3 From mbruni at codeweavers.com Mon Oct 3 16:46:56 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Mon, 3 Oct 2016 23:46:56 +0200 Subject: [PATCH 6/6] wined3d: Use ARB_clip_control to avoid vertex position fixups. In-Reply-To: <1475531216-20874-1-git-send-email-mbruni@codeweavers.com> References: <1475531216-20874-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1475531216-20874-6-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- FTR, next in the queue there are a couple tests for the derivative shader instructions. dlls/wined3d/arb_program_shader.c | 32 ++++++++++---------- dlls/wined3d/context.c | 15 ++++++++-- dlls/wined3d/directx.c | 17 +++++++++++ dlls/wined3d/glsl_shader.c | 26 +++++++++++----- dlls/wined3d/state.c | 63 +++++++++++++++++++++++++++++++++++++++ dlls/wined3d/utils.c | 26 +++++++++------- 6 files changed, 143 insertions(+), 36 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index f8ecb80..87794ea 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -3264,22 +3264,24 @@ static void vshader_add_footer(struct shader_arb_ctx_priv *priv_ctx, * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x * contains 1.0 to allow a mad, but arb vs swizzles are too restricted for that. */ - shader_addline(buffer, "MUL TA, posFixup, TMP_OUT.w;\n"); - shader_addline(buffer, "ADD TMP_OUT.x, TMP_OUT.x, TA.z;\n"); - shader_addline(buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, TA.w;\n"); - - /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c - * and the glsl equivalent - */ - if (need_helper_const(shader_data, reg_maps, gl_info)) - { - const char *two = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_TWO); - shader_addline(buffer, "MAD TMP_OUT.z, TMP_OUT.z, %s, -TMP_OUT.w;\n", two); - } - else + if (!gl_info->supported[ARB_CLIP_CONTROL]) { - shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, TMP_OUT.z;\n"); - shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, -TMP_OUT.w;\n"); + shader_addline(buffer, "MUL TA, posFixup, TMP_OUT.w;\n"); + shader_addline(buffer, "ADD TMP_OUT.x, TMP_OUT.x, TA.z;\n"); + shader_addline(buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, TA.w;\n"); + + /* Z coord [0;1]->[-1;1] mapping, see comment in + * get_projection_matrix() in utils.c. */ + if (need_helper_const(shader_data, reg_maps, gl_info)) + { + const char *two = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_TWO); + shader_addline(buffer, "MAD TMP_OUT.z, TMP_OUT.z, %s, -TMP_OUT.w;\n", two); + } + else + { + shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, TMP_OUT.z;\n"); + shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, -TMP_OUT.w;\n"); + } } shader_addline(buffer, "MOV result.position, TMP_OUT;\n"); diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 8c08310..fa47850 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1971,6 +1971,8 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, { GL_EXTCALL(glProvokingVertexEXT(GL_FIRST_VERTEX_CONVENTION_EXT)); } + if (gl_info->supported[ARB_CLIP_CONTROL]) + GL_EXTCALL(glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT)); device->shader_backend->shader_init_context_state(ret); ret->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL) | (1u << WINED3D_SHADER_TYPE_VERTEX) @@ -2261,6 +2263,10 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING)); + /* FIXME: Make draw_textured_quad() able to work with a upper left origin. */ + if (gl_info->supported[ARB_CLIP_CONTROL]) + GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE)); + set_blit_dimension(gl_info, rt_size.cx, rt_size.cy); /* Disable shaders */ @@ -2413,11 +2419,14 @@ static void context_set_render_offscreen(struct wined3d_context *context, BOOL o { if (context->render_offscreen == offscreen) return; - context_invalidate_state(context, STATE_POINTSPRITECOORDORIGIN); - context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); context_invalidate_state(context, STATE_VIEWPORT); context_invalidate_state(context, STATE_SCISSORRECT); - context_invalidate_state(context, STATE_FRONTFACE); + if (!context->gl_info->supported[ARB_CLIP_CONTROL]) + { + context_invalidate_state(context, STATE_FRONTFACE); + context_invalidate_state(context, STATE_POINTSPRITECOORDORIGIN); + context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)); + } if (context->gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) context_invalidate_state(context, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); context->render_offscreen = offscreen; diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index b03ddf6..5d91981 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -3856,6 +3856,23 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD if (!counter_bits) gl_info->supported[ARB_TIMER_QUERY] = FALSE; } + if (gl_info->supported[ARB_VIEWPORT_ARRAY]) + { + GLint subpixel_bits; + + gl_info->gl_ops.gl.p_glGetIntegerv(GL_VIEWPORT_SUBPIXEL_BITS, &subpixel_bits); + TRACE("Viewport supports %d subpixel bits.\n", subpixel_bits); + if (!subpixel_bits) + gl_info->supported[ARB_VIEWPORT_ARRAY] = FALSE; + } + if (gl_info->supported[ARB_CLIP_CONTROL] && !gl_info->supported[ARB_VIEWPORT_ARRAY]) + { + /* When using ARB_clip_control we need the float viewport parameters + * introduced by ARB_viewport_array to take care of the shifted pixel + * coordinates. */ + TRACE("Disabling ARB_clip_control because ARB_viewport_array is not supported.\n"); + gl_info->supported[ARB_CLIP_CONTROL] = FALSE; + } if (!gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] && gl_info->supported[EXT_TEXTURE_MIRROR_CLAMP]) { TRACE(" IMPLIED: ATI_texture_mirror_once support (by EXT_texture_mirror_clamp).\n"); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 72740af..0a7af72 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -4398,7 +4398,8 @@ static void shader_glsl_emit(const struct wined3d_shader_instruction *ins) unsigned int stream = ins->handler_idx == WINED3DSIH_EMIT ? 0 : ins->src[0].reg.idx[0].offset; shader_addline(ins->ctx->buffer, "setup_gs_output(gs_out);\n"); - shader_glsl_fixup_position(ins->ctx->buffer); + if (!ins->ctx->gl_info->supported[ARB_CLIP_CONTROL]) + shader_glsl_fixup_position(ins->ctx->buffer); if (!stream) shader_addline(ins->ctx->buffer, "EmitVertex();\n"); @@ -6046,7 +6047,7 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context /* Base Declarations */ shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); - if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL) + if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL]) shader_addline(buffer, "uniform vec4 pos_fixup;\n"); if (reg_maps->shader_version.major >= 4) @@ -6093,7 +6094,7 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context if (args->point_size && !args->per_vertex_point_size) shader_addline(buffer, "gl_PointSize = clamp(ffp_point.size, ffp_point.size_min, ffp_point.size_max);\n"); - if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL) + if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL]) shader_glsl_fixup_position(buffer); shader_addline(buffer, "}\n"); @@ -6127,7 +6128,8 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context memset(&priv_ctx, 0, sizeof(priv_ctx)); priv_ctx.string_buffers = string_buffers; shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); - shader_addline(buffer, "uniform vec4 pos_fixup;\n"); + if (!gl_info->supported[ARB_CLIP_CONTROL]) + shader_addline(buffer, "uniform vec4 pos_fixup;\n"); shader_glsl_generate_sm4_rasterizer_input_setup(priv, shader, args->ps_input_count, gl_info); shader_addline(buffer, "void main()\n{\n"); shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx); @@ -6767,12 +6769,21 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr case WINED3D_FFP_VS_FOG_DEPTH: if (settings->ortho_fog) - /* Need to undo the [0.0 - 1.0] -> [-1.0 - 1.0] transformation from D3D to GL coordinates. */ - shader_addline(buffer, "ffp_varying_fogcoord = gl_Position.z * 0.5 + 0.5;\n"); + { + if (gl_info->supported[ARB_CLIP_CONTROL]) + shader_addline(buffer, "ffp_varying_fogcoord = gl_Position.z;\n"); + else + /* Need to undo the [0.0 - 1.0] -> [-1.0 - 1.0] transformation from D3D to GL coordinates. */ + shader_addline(buffer, "ffp_varying_fogcoord = gl_Position.z * 0.5 + 0.5;\n"); + } else if (settings->transformed) + { shader_addline(buffer, "ffp_varying_fogcoord = ec_pos.z;\n"); + } else + { shader_addline(buffer, "ffp_varying_fogcoord = abs(ec_pos.z);\n"); + } break; default: @@ -7994,7 +8005,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const if (gshader) { - entry->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; + if (entry->gs.pos_fixup_location != -1) + entry->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; shader_glsl_init_uniform_block_bindings(gl_info, priv, program_id, &gshader->reg_maps); shader_glsl_load_icb(gl_info, priv, program_id, &gshader->reg_maps); } diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 1b0d018..3b96acc 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -4648,6 +4648,55 @@ static void viewport_miscpart(struct wined3d_context *context, const struct wine checkGLcall("glViewport"); } +static void viewport_miscpart_cc(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_rendertarget_view *depth_stencil = state->fb->depth_stencil; + const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; + float pixel_center_offset = context->swapchain->device->wined3d->flags + & WINED3D_PIXEL_CENTER_INTEGER ? 0.5f : 0.0f; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_viewport vp = state->viewport; + unsigned int width, height; + + if (target) + { + if (vp.width > target->width) + vp.width = target->width; + if (vp.height > target->height) + vp.height = target->height; + + surface_get_drawable_size(wined3d_rendertarget_view_get_surface(target), context, &width, &height); + } + else if (depth_stencil) + { + width = depth_stencil->width; + height = depth_stencil->height; + } + else + { + FIXME("No attachments draw calls not supported.\n"); + return; + } + + gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z); + checkGLcall("glDepthRange"); + + if (context->render_offscreen) + { + GL_EXTCALL(glClipControl(GL_UPPER_LEFT, GL_ZERO_TO_ONE)); + GL_EXTCALL(glViewportIndexedf(0, vp.x + pixel_center_offset, vp.y + pixel_center_offset, + vp.width, vp.height)); + } + else + { + GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE)); + GL_EXTCALL(glViewportIndexedf(0, vp.x + pixel_center_offset, + (height - (vp.y + vp.height)) + pixel_center_offset, vp.width, vp.height)); + } + checkGLcall("setting clip space and viewport"); +} + static void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))) @@ -4837,6 +4886,17 @@ static void frontface(struct wined3d_context *context, const struct wined3d_stat checkGLcall("glFrontFace"); } +static void frontface_cc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + GLenum mode; + + mode = state->rasterizer_state && state->rasterizer_state->desc.front_ccw ? GL_CCW : GL_CW; + + gl_info->gl_ops.gl.p_glFrontFace(mode); + checkGLcall("glFrontFace"); +} + static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { static BOOL warned; @@ -4923,8 +4983,10 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_RENDER(WINED3D_RS_BLENDOPALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE }, { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE }, + { STATE_FRONTFACE, { STATE_FRONTFACE, frontface_cc }, ARB_CLIP_CONTROL }, { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE }, { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE }, + { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, state_nop }, ARB_CLIP_CONTROL }, { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 }, { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin_w }, WINED3D_GL_EXT_NONE }, @@ -4980,6 +5042,7 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart_cc}, ARB_CLIP_CONTROL }, { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE }, { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT }, { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 0dae0d0..173b028 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -4494,6 +4494,8 @@ void get_modelview_matrix(const struct wined3d_context *context, const struct wi void get_projection_matrix(const struct wined3d_context *context, const struct wined3d_state *state, struct wined3d_matrix *mat) { + BOOL clip_control = context->gl_info->supported[ARB_CLIP_CONTROL]; + BOOL flip = !clip_control && context->render_offscreen; float center_offset; /* There are a couple of additional things we have to take into account @@ -4511,7 +4513,7 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w * driver, but small enough to prevent it from interfering with any * anti-aliasing. */ - if (context->swapchain->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) + if (!clip_control && context->swapchain->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) center_offset = 63.0f / 64.0f; else center_offset = -1.0f / 64.0f; @@ -4525,14 +4527,14 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w float h = state->viewport.height; float x_scale = 2.0f / w; float x_offset = (center_offset - (2.0f * x) - w) / w; - float y_scale = context->render_offscreen ? 2.0f / h : 2.0f / -h; - float y_offset = context->render_offscreen + float y_scale = flip ? 2.0f / h : 2.0f / -h; + float y_offset = flip ? (center_offset - (2.0f * y) - h) / h : (center_offset - (2.0f * y) - h) / -h; enum wined3d_depth_buffer_type zenable = state->fb->depth_stencil ? state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE; - float z_scale = zenable ? 2.0f : 0.0f; - float z_offset = zenable ? -1.0f : 0.0f; + float z_scale = zenable ? clip_control ? 1.0f : 2.0f : 0.0f; + float z_offset = zenable ? clip_control ? 0.0f : -1.0f : 0.0f; const struct wined3d_matrix projection = { x_scale, 0.0f, 0.0f, 0.0f, @@ -4545,17 +4547,19 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w } else { - float y_scale = context->render_offscreen ? -1.0f : 1.0f; + float y_scale = flip ? -1.0f : 1.0f; float x_offset = center_offset / state->viewport.width; - float y_offset = context->render_offscreen + float y_offset = flip ? center_offset / state->viewport.height : -center_offset / state->viewport.height; + float z_scale = clip_control ? 1.0f : 2.0f; + float z_offset = clip_control ? 0.0f : -1.0f; const struct wined3d_matrix projection = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, y_scale, 0.0f, 0.0f, - 0.0f, 0.0f, 2.0f, 0.0f, - x_offset, y_offset, -1.0f, 1.0f, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, y_scale, 0.0f, 0.0f, + 0.0f, 0.0f, z_scale, 0.0f, + x_offset, y_offset, z_offset, 1.0f, }; multiply_matrix(mat, &projection, &state->transforms[WINED3D_TS_PROJECTION]); -- 2.7.3 From ken at codeweavers.com Mon Oct 3 23:06:40 2016 From: ken at codeweavers.com (Ken Thomases) Date: Mon, 3 Oct 2016 23:06:40 -0500 Subject: [PATCH] winemac.drv: Use EqualRect() instead of memcmp() to compare RECTs. In-Reply-To: References: Message-ID: <1B658AAF-F547-4373-A901-11A1D2359484@codeweavers.com> Signed-off-by: Ken Thomases From piotr at codeweavers.com Tue Oct 4 03:09:58 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Tue, 4 Oct 2016 10:09:58 +0200 Subject: [PATCH 1/2] msvcp110: Fix cin/cout/cerr/clog structure sizes Message-ID: <6e27e7c5-7183-6393-5d06-dea00b59962d@codeweavers.com> Signed-off-by: Piotr Caban --- dlls/msvcp90/ios.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-msvcp110-Fix-cin-cout-cerr-clog-structure-sizes.txt Type: text/x-patch Size: 6945 bytes Desc: not available URL: From piotr at codeweavers.com Tue Oct 4 03:10:05 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Tue, 4 Oct 2016 10:10:05 +0200 Subject: [PATCH 2/2] msvcp140/tests: Test virtual base table size exports Message-ID: Signed-off-by: Piotr Caban --- dlls/msvcp140/tests/msvcp140.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-msvcp140-tests-Test-virtual-base-table-size-exports.txt Type: text/x-patch Size: 2277 bytes Desc: not available URL: From hverbeet at codeweavers.com Tue Oct 4 05:16:44 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Tue, 4 Oct 2016 12:16:44 +0200 Subject: [v3 PATCH] d2d1: Initial implementation of HWND render target In-Reply-To: <20161003155611.3798-1-nsivov@codeweavers.com> References: <20161003155611.3798-1-nsivov@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Tue Oct 4 05:16:44 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Tue, 4 Oct 2016 12:16:44 +0200 Subject: [PATCH v2 2/6] wined3d: Avoid vpos fixups when ARB_fragment_coord_conventions is supported. In-Reply-To: <1475531216-20874-2-git-send-email-mbruni@codeweavers.com> References: <1475531216-20874-2-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Tue Oct 4 05:16:45 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Tue, 4 Oct 2016 12:16:45 +0200 Subject: [PATCH 3/6] wined3d: Add core version of the functions introduced by EXT_draw_buffers2. In-Reply-To: <1475531216-20874-3-git-send-email-mbruni@codeweavers.com> References: <1475531216-20874-3-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Tue Oct 4 05:16:46 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Tue, 4 Oct 2016 12:16:46 +0200 Subject: [PATCH resend 1/6] wined3d: Add ARB_fragment_coord_conventions extension. In-Reply-To: <1475531216-20874-1-git-send-email-mbruni@codeweavers.com> References: <1475531216-20874-1-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Tue Oct 4 05:16:47 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Tue, 4 Oct 2016 12:16:47 +0200 Subject: [PATCH 4/6] wined3d: Add ARB_viewport_array extension. In-Reply-To: <1475531216-20874-4-git-send-email-mbruni@codeweavers.com> References: <1475531216-20874-4-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Tue Oct 4 05:16:48 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Tue, 4 Oct 2016 12:16:48 +0200 Subject: [PATCH 5/6] wined3d: Add ARB_clip_control extension. In-Reply-To: <1475531216-20874-5-git-send-email-mbruni@codeweavers.com> References: <1475531216-20874-5-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Tue Oct 4 05:16:49 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Tue, 4 Oct 2016 12:16:49 +0200 Subject: [PATCH 6/6] wined3d: Use ARB_clip_control to avoid vertex position fixups. In-Reply-To: <1475531216-20874-6-git-send-email-mbruni@codeweavers.com> References: <1475531216-20874-6-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From aric at codeweavers.com Tue Oct 4 05:35:35 2016 From: aric at codeweavers.com (Aric Stewart) Date: Tue, 4 Oct 2016 05:35:35 -0500 Subject: [PATCH v2] hidclass.sys: minidriver handling for IRP_MN_REMOVE_DEVICE finished the IRP Message-ID: <70bc7a83-81fb-ebf1-d26c-32c997db4933@codeweavers.com> v2: remove unnecessary break Signed-off-by: Aric Stewart --- dlls/hidclass.sys/pnp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: v2-0001-hidclass.sys-minidriver-handling-for-IRP_MN_REMOVE_.txt Type: text/x-patch Size: 520 bytes Desc: not available URL: From hans at codeweavers.com Tue Oct 4 06:28:32 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Tue, 4 Oct 2016 13:28:32 +0200 Subject: advapi32: Add a stub implementation of EnableTraceEx2. Message-ID: <1475580516-21147-1-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/advapi32/advapi32.spec | 2 +- dlls/advapi32/eventlog.c | 14 ++++++++++++++ include/evntrace.h | 13 +++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec index c2a8d01..b1a051c 100644 --- a/dlls/advapi32/advapi32.spec +++ b/dlls/advapi32/advapi32.spec @@ -248,7 +248,7 @@ @ stub ElfReportEventW @ stdcall EnableTrace(long long long ptr int64) @ stdcall EnableTraceEx(ptr ptr int64 long long int64 int64 long ptr) -# @ stub EnableTraceEx2 +@ stdcall EnableTraceEx2(int64 ptr long long int64 int64 long ptr) @ stdcall EncryptFileA(str) @ stdcall EncryptFileW(wstr) # @ stub EncryptedFileKeyInfo diff --git a/dlls/advapi32/eventlog.c b/dlls/advapi32/eventlog.c index f947511..893f6e5 100644 --- a/dlls/advapi32/eventlog.c +++ b/dlls/advapi32/eventlog.c @@ -239,6 +239,20 @@ ULONG WINAPI EnableTraceEx( LPCGUID provider, LPCGUID source, TRACEHANDLE hSessi } /****************************************************************************** + * EnableTraceEx2 [ADVAPI32.@] + */ +ULONG WINAPI EnableTraceEx2( TRACEHANDLE handle, LPCGUID provider, ULONG control, UCHAR level, + ULONGLONG match_any, ULONGLONG match_all, ULONG timeout, + PENABLE_TRACE_PARAMETERS params ) +{ + FIXME("(%s, %s, %u, %c, %s, %s, %u, %p): stub\n", wine_dbgstr_longlong(handle), + debugstr_guid(provider), control, level, wine_dbgstr_longlong(match_any), + wine_dbgstr_longlong(match_all), timeout, params); + + return ERROR_SUCCESS; +} + +/****************************************************************************** * EnableTrace [ADVAPI32.@] */ ULONG WINAPI EnableTrace( ULONG enable, ULONG flag, ULONG level, LPCGUID guid, TRACEHANDLE hSession ) diff --git a/include/evntrace.h b/include/evntrace.h index 191f232..6ebcfba 100644 --- a/include/evntrace.h +++ b/include/evntrace.h @@ -248,6 +248,18 @@ typedef struct _EVENT_TRACE_PROPERTIES ULONG LoggerNameOffset; } EVENT_TRACE_PROPERTIES, *PEVENT_TRACE_PROPERTIES; +typedef struct _EVENT_FILTER_DESCRIPTOR EVENT_FILTER_DESCRIPTOR, *PEVENT_FILTER_DESCRIPTOR; + +typedef struct _ENABLE_TRACE_PARAMETERS +{ + ULONG Version; + ULONG EnableProperty; + ULONG ControlFlags; + GUID SourceId; + PEVENT_FILTER_DESCRIPTOR EnableFilterDesc; + ULONG FilterDescCount; +} ENABLE_TRACE_PARAMETERS, *PENABLE_TRACE_PARAMETERS; + #define INVALID_PROCESSTRACE_HANDLE ((TRACEHANDLE)~(ULONG_PTR)0) ULONG WINAPI CloseTrace(TRACEHANDLE); @@ -255,6 +267,7 @@ ULONG WINAPI ControlTraceA(TRACEHANDLE,LPCSTR,PEVENT_TRACE_PROPERTIES,ULONG); ULONG WINAPI ControlTraceW(TRACEHANDLE,LPCWSTR,PEVENT_TRACE_PROPERTIES,ULONG); #define ControlTrace WINELIB_NAME_AW(ControlTrace) ULONG WINAPI EnableTrace(ULONG,ULONG,ULONG,LPCGUID,TRACEHANDLE); +ULONG WINAPI EnableTraceEx2(TRACEHANDLE,LPCGUID,ULONG,UCHAR,ULONGLONG,ULONGLONG,ULONG,PENABLE_TRACE_PARAMETERS); ULONG WINAPI FlushTraceA(TRACEHANDLE,LPCSTR,PEVENT_TRACE_PROPERTIES); ULONG WINAPI FlushTraceW(TRACEHANDLE,LPCWSTR,PEVENT_TRACE_PROPERTIES); #define FlushTrace WINELIB_NAME_AW(FlushTrace) -- 2.1.4 From hans at codeweavers.com Tue Oct 4 06:28:33 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Tue, 4 Oct 2016 13:28:33 +0200 Subject: ntdll: szCSDVersion is an empty string on Windows 8 and up. Message-ID: <1475580516-21147-2-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/kernel32/tests/version.c | 3 +++ dlls/ntdll/version.c | 9 +++------ programs/winecfg/appdefaults.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dlls/kernel32/tests/version.c b/dlls/kernel32/tests/version.c index a47e52c..4182c06 100644 --- a/dlls/kernel32/tests/version.c +++ b/dlls/kernel32/tests/version.c @@ -156,6 +156,9 @@ static void test_GetVersionEx(void) ok(ret || broken(ret == 0), /* win95 */ "Expected GetVersionExA to succeed\n"); + + if (!infoExA.wServicePackMajor && !infoExA.wServicePackMinor) + ok(!infoExA.szCSDVersion[0], "got '%s'\n", infoExA.szCSDVersion); } static void test_VerifyVersionInfo(void) diff --git a/dlls/ntdll/version.c b/dlls/ntdll/version.c index b6cafc6..06f9827 100644 --- a/dlls/ntdll/version.c +++ b/dlls/ntdll/version.c @@ -176,20 +176,17 @@ static const RTL_OSVERSIONINFOEXW VersionData[NB_WINDOWS_VERSIONS] = /* WIN8 */ { sizeof(RTL_OSVERSIONINFOEXW), 6, 2, 0x23F0, VER_PLATFORM_WIN32_NT, - {' ',0}, - 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0 + {0}, 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0 }, /* WIN81 */ { sizeof(RTL_OSVERSIONINFOEXW), 6, 3, 0x2580, VER_PLATFORM_WIN32_NT, - {' ',0}, - 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0 + {0}, 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0 }, /* WIN10 */ { sizeof(RTL_OSVERSIONINFOEXW), 10, 0, 0x3839, VER_PLATFORM_WIN32_NT, - {' ',0}, - 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0 + {0}, 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0 }, }; diff --git a/programs/winecfg/appdefaults.c b/programs/winecfg/appdefaults.c index 91478fc..f674824 100644 --- a/programs/winecfg/appdefaults.c +++ b/programs/winecfg/appdefaults.c @@ -48,9 +48,9 @@ static const struct const char *szProductType; } win_versions[] = { - { "win10", "Windows 10", 10, 0, 0x3839,VER_PLATFORM_WIN32_NT, " ", 0, 0, "WinNT"}, - { "win81", "Windows 8.1", 6, 3, 0x2580,VER_PLATFORM_WIN32_NT, " ", 0, 0, "WinNT"}, - { "win8", "Windows 8", 6, 2, 0x23F0,VER_PLATFORM_WIN32_NT, " ", 0, 0, "WinNT"}, + { "win10", "Windows 10", 10, 0, 0x3839,VER_PLATFORM_WIN32_NT, "", 0, 0, "WinNT"}, + { "win81", "Windows 8.1", 6, 3, 0x2580,VER_PLATFORM_WIN32_NT, "", 0, 0, "WinNT"}, + { "win8", "Windows 8", 6, 2, 0x23F0,VER_PLATFORM_WIN32_NT, "", 0, 0, "WinNT"}, { "win2008r2", "Windows 2008 R2", 6, 1, 0x1DB1,VER_PLATFORM_WIN32_NT, "Service Pack 1", 1, 0, "ServerNT"}, { "win7", "Windows 7", 6, 1, 0x1DB1,VER_PLATFORM_WIN32_NT, "Service Pack 1", 1, 0, "WinNT"}, { "win2008", "Windows 2008", 6, 0, 0x1772,VER_PLATFORM_WIN32_NT, "Service Pack 2", 2, 0, "ServerNT"}, -- 2.1.4 From hans at codeweavers.com Tue Oct 4 06:28:34 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Tue, 4 Oct 2016 13:28:34 +0200 Subject: [1/3] webservices: Add support for writing WS_DATETIME values. Message-ID: <1475580516-21147-3-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/reader.c | 23 +------- dlls/webservices/tests/writer.c | 88 ++++++++++++++++++++++++++++++ dlls/webservices/webservices_private.h | 18 +++++++ dlls/webservices/writer.c | 98 ++++++++++++++++++++++++++++++++++ include/webservices.h | 6 +++ 5 files changed, 212 insertions(+), 21 deletions(-) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index eb4bb7b..d106b18 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -2468,32 +2468,15 @@ static HRESULT str_to_guid( const unsigned char *str, ULONG len, GUID *ret ) return S_OK; } -#define TICKS_PER_SEC 10000000 -#define TICKS_PER_MIN (60 * (ULONGLONG)TICKS_PER_SEC) -#define TICKS_PER_HOUR (3600 * (ULONGLONG)TICKS_PER_SEC) -#define TICKS_PER_DAY (86400 * (ULONGLONG)TICKS_PER_SEC) -#define TICKS_MAX 3155378975999999999 - static const int month_offsets[2][12] = { {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} }; -static const int month_days[2][12] = -{ - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -}; - -static inline int is_leap_year( int year ) -{ - return !(year % 4) && (year % 100 || !(year % 400)); -} - static inline int valid_day( int year, int month, int day ) { - return day > 0 && day <= month_days[is_leap_year( year )][month - 1]; + return day > 0 && day <= month_days[leap_year( year )][month - 1]; } static inline int leap_days_before( int year ) @@ -2585,7 +2568,7 @@ static HRESULT str_to_datetime( const unsigned char *bytes, ULONG len, WS_DATETI else return WS_E_INVALID_FORMAT; ret->ticks = ((year - 1) * 365 + leap_days_before( year )) * TICKS_PER_DAY; - ret->ticks += month_offsets[is_leap_year( year )][month - 1] * TICKS_PER_DAY; + ret->ticks += month_offsets[leap_year( year )][month - 1] * TICKS_PER_DAY; ret->ticks += (day - 1) * TICKS_PER_DAY; ret->ticks += hour * TICKS_PER_HOUR; ret->ticks += min * TICKS_PER_MIN; @@ -2610,8 +2593,6 @@ static HRESULT str_to_datetime( const unsigned char *bytes, ULONG len, WS_DATETI return S_OK; } -#define TICKS_1601_01_01 504911232000000000 - /************************************************************************** * WsDateTimeToFileTime [webservices.@] */ diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index 2309ab5..c817615 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -2547,6 +2547,93 @@ static void test_write_option(void) WsFreeWriter( writer ); } +static BOOL check_result( WS_XML_WRITER *writer, const char *expected ) +{ + WS_BYTES bytes; + ULONG size = sizeof(bytes); + int len = strlen( expected ); + + memset( &bytes, 0, sizeof(bytes) ); + WsGetWriterProperty( writer, WS_XML_WRITER_PROPERTY_BYTES, &bytes, size, NULL ); + if (bytes.length != len) return FALSE; + return !memcmp( bytes.bytes, expected, len ); +} + +static void test_datetime(void) +{ + WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL}; + static const struct + { + unsigned __int64 ticks; + WS_DATETIME_FORMAT format; + HRESULT hr; + const char *result; + const char *result2; + } + tests[] = + { + { 0, WS_DATETIME_FORMAT_UTC, S_OK, "0001-01-01T00:00:00Z" }, + { 0, WS_DATETIME_FORMAT_LOCAL, S_OK, "0001-01-01T00:00:00+00:00" }, + { 0, WS_DATETIME_FORMAT_NONE, S_OK, "0001-01-01T00:00:00" }, + { 1, WS_DATETIME_FORMAT_UTC, S_OK, "0001-01-01T00:00:00.0000001Z" }, + { 1, WS_DATETIME_FORMAT_LOCAL, S_OK, "0001-01-01T00:00:00.0000001+00:00" }, + { 1, WS_DATETIME_FORMAT_NONE, S_OK, "0001-01-01T00:00:00.0000001" }, + { 0x23c34600, WS_DATETIME_FORMAT_LOCAL, S_OK, "0001-01-01T00:01:00+00:00" }, + { 0x861c46800, WS_DATETIME_FORMAT_LOCAL, S_OK, "0001-01-01T01:00:00+00:00" }, + { 0x430e234000, WS_DATETIME_FORMAT_LOCAL, S_OK, "0001-01-01T08:00:00+00:00" }, + { 0x4b6fe7a800, WS_DATETIME_FORMAT_LOCAL, S_OK, "0001-01-01T09:00:00+00:00" }, + { 0x989680, WS_DATETIME_FORMAT_NONE, S_OK, "0001-01-01T00:00:01" }, + { 0x23c34600, WS_DATETIME_FORMAT_NONE, S_OK, "0001-01-01T00:01:00" }, + { 0x861c46800, WS_DATETIME_FORMAT_NONE, S_OK, "0001-01-01T01:00:00" }, + { 0xc92a69c000, WS_DATETIME_FORMAT_NONE, S_OK, "0001-01-02T00:00:00" }, + { 0x11ed178c6c000, WS_DATETIME_FORMAT_NONE, S_OK, "0002-01-01T00:00:00" }, + { 0x2bca2875f4373fff, WS_DATETIME_FORMAT_UTC, S_OK, "9999-12-31T23:59:59.9999999Z" }, + { 0x2bca2875f4373fff, WS_DATETIME_FORMAT_LOCAL, S_OK, "9999-12-31T15:59:59.9999999-08:00", + "9999-12-31T17:59:59.9999999-06:00" /* win7 */ }, + { 0x2bca2875f4373fff, WS_DATETIME_FORMAT_NONE, S_OK, "9999-12-31T23:59:59.9999999" }, + { 0x2bca2875f4374000, WS_DATETIME_FORMAT_UTC, WS_E_INVALID_FORMAT }, + { 0x2bca2875f4374000, WS_DATETIME_FORMAT_LOCAL, WS_E_INVALID_FORMAT }, + { 0x2bca2875f4374000, WS_DATETIME_FORMAT_NONE, WS_E_INVALID_FORMAT }, + { 0x8d3123e7df74000, WS_DATETIME_FORMAT_LOCAL, S_OK, "2015-12-31T16:00:00-08:00", + "2015-12-31T18:00:00-06:00" /* win7 */ }, + { 0x701ce1722770000, WS_DATETIME_FORMAT_LOCAL, S_OK, "1601-01-01T00:00:00+00:00" }, + { 0x701ce5a309a4000, WS_DATETIME_FORMAT_LOCAL, S_OK, "1601-01-01T00:00:00-08:00", + "1601-01-01T02:00:00-06:00" /* win7 */ }, + { 0x701ce5e617c7400, WS_DATETIME_FORMAT_LOCAL, S_OK, "1601-01-01T00:30:00-08:00", + "1601-01-01T02:30:00-06:00" /* win7 */ }, + { 0x701ce51ced5d800, WS_DATETIME_FORMAT_LOCAL, S_OK, "1601-01-01T07:00:00+00:00", + "1601-01-01T01:00:00-06:00" /* win7 */ }, + { 0, WS_DATETIME_FORMAT_NONE + 1, WS_E_INVALID_FORMAT }, + }; + HRESULT hr; + WS_XML_WRITER *writer; + WS_DATETIME date; + ULONG i; + + hr = WsCreateWriter( NULL, 0, &writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + { + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + date.ticks = tests[i].ticks; + date.format = tests[i].format; + WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_DATETIME_TYPE, NULL, WS_WRITE_REQUIRED_VALUE, + &date, sizeof(date), NULL ); + WsWriteEndElement( writer, NULL ); + ok( hr == tests[i].hr, "%u: got %08x\n", i, hr ); + if (hr == S_OK) + { + ok( check_result( writer, tests[i].result ) || broken(check_result( writer, tests[i].result2 )), + "%u: wrong result\n", i ); + } + } + + WsFreeWriter( writer ); +} + START_TEST(writer) { test_WsCreateWriter(); @@ -2578,4 +2665,5 @@ START_TEST(writer) test_WsWriteArray(); test_escapes(); test_write_option(); + test_datetime(); } diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h index f72d2b9..cdaa4b5 100644 --- a/dlls/webservices/webservices_private.h +++ b/dlls/webservices/webservices_private.h @@ -100,6 +100,24 @@ HRESULT message_insert_http_headers( WS_MESSAGE *, HINTERNET ) DECLSPEC_HIDDEN; HRESULT channel_send_message( WS_CHANNEL *, WS_MESSAGE * ) DECLSPEC_HIDDEN; HRESULT channel_receive_message( WS_CHANNEL *, char **, ULONG * ) DECLSPEC_HIDDEN; +#define TICKS_PER_SEC 10000000 +#define TICKS_PER_MIN (60 * (ULONGLONG)TICKS_PER_SEC) +#define TICKS_PER_HOUR (3600 * (ULONGLONG)TICKS_PER_SEC) +#define TICKS_PER_DAY (86400 * (ULONGLONG)TICKS_PER_SEC) +#define TICKS_MAX 3155378975999999999 +#define TICKS_1601_01_01 504911232000000000 + +static const int month_days[2][12] = +{ + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} +}; + +static inline int leap_year( int year ) +{ + return !(year % 4) && (year % 100 || !(year % 400)); +} + static inline BOOL is_nil_value( const char *value, ULONG size ) { ULONG i; diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index cc734d2..7a818eb 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -1187,6 +1187,68 @@ static ULONG format_double( const double *ptr, unsigned char *buf ) #endif } +static inline int year_size( int year ) +{ + return leap_year( year ) ? 366 : 365; +} + +#define TZ_OFFSET 8 +static ULONG format_datetime( const WS_DATETIME *ptr, unsigned char *buf ) +{ + static const char fmt[] = "%04u-%02u-%02uT%02u:%02u:%02u"; + int day, hour, min, sec, sec_frac, month = 1, year = 1, tz_hour; + unsigned __int64 ticks, day_ticks; + ULONG len; + + if (ptr->format == WS_DATETIME_FORMAT_LOCAL && + ptr->ticks >= TICKS_1601_01_01 + TZ_OFFSET * TICKS_PER_HOUR) + { + ticks = ptr->ticks - TZ_OFFSET * TICKS_PER_HOUR; + tz_hour = TZ_OFFSET; + } + else + { + ticks = ptr->ticks; + tz_hour = 0; + } + day = ticks / TICKS_PER_DAY; + day_ticks = ticks % TICKS_PER_DAY; + hour = day_ticks / TICKS_PER_HOUR; + min = (day_ticks % TICKS_PER_HOUR) / TICKS_PER_MIN; + sec = (day_ticks % TICKS_PER_MIN) / TICKS_PER_SEC; + sec_frac = day_ticks % TICKS_PER_SEC; + + while (day >= year_size( year )) + { + day -= year_size( year ); + year++; + } + while (day >= month_days[leap_year( year )][month]) + { + day -= month_days[leap_year( year )][month]; + month++; + } + day++; + + len = sprintf( (char *)buf, fmt, year, month, day, hour, min, sec ); + if (sec_frac) + { + static const char fmt_frac[] = ".%07u"; + len += sprintf( (char *)buf + len, fmt_frac, sec_frac ); + } + if (ptr->format == WS_DATETIME_FORMAT_UTC) + { + buf[len++] = 'Z'; + } + else if (ptr->format == WS_DATETIME_FORMAT_LOCAL) + { + static const char fmt_tz[] = "%c%02u:00"; + len += sprintf( (char *)buf + len, fmt_tz, tz_hour ? '-' : '+', tz_hour ); + } + + return len; +} + static ULONG format_guid( const GUID *ptr, unsigned char *buf ) { static const char fmt[] = "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"; @@ -1284,6 +1346,13 @@ static HRESULT text_to_utf8text( const WS_XML_TEXT *text, WS_XML_UTF8_TEXT **ret (*ret)->value.length = format_urn( &id->value, (*ret)->value.bytes ); return S_OK; } + case WS_XML_TEXT_TYPE_DATETIME: + { + const WS_XML_DATETIME_TEXT *dt = (const WS_XML_DATETIME_TEXT *)text; + if (!(*ret = alloc_utf8_text( NULL, 34 ))) return E_OUTOFMEMORY; + (*ret)->value.length = format_datetime( &dt->value, (*ret)->value.bytes ); + return S_OK; + } default: FIXME( "unhandled text type %u\n", text->textType ); return E_NOTIMPL; @@ -1666,6 +1735,32 @@ static HRESULT write_type_uint64( struct writer *writer, WS_TYPE_MAPPING mapping return write_type_text( writer, mapping, &utf8.text ); } +static HRESULT write_type_datetime( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_DATETIME_DESCRIPTION *desc, WS_WRITE_OPTION option, + const void *value, ULONG size ) +{ + WS_XML_UTF8_TEXT utf8; + unsigned char buf[34]; /* "0000-00-00T00:00:00.0000000-00:00" */ + const WS_DATETIME *ptr; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + + if (!option || option == WS_WRITE_NILLABLE_VALUE) return E_INVALIDARG; + if ((hr = get_value_ptr( option, value, size, sizeof(WS_DATETIME), (const void **)&ptr )) != S_OK) return hr; + if (option == WS_WRITE_NILLABLE_POINTER && !ptr) return write_add_nil_attribute( writer ); + if (ptr->ticks > TICKS_MAX || ptr->format > WS_DATETIME_FORMAT_NONE) return WS_E_INVALID_FORMAT; + + utf8.text.textType = WS_XML_TEXT_TYPE_UTF8; + utf8.value.bytes = buf; + utf8.value.length = format_datetime( ptr, buf ); + return write_type_text( writer, mapping, &utf8.text ); +} + static HRESULT write_type_guid( struct writer *writer, WS_TYPE_MAPPING mapping, const WS_GUID_DESCRIPTION *desc, WS_WRITE_OPTION option, const void *value, ULONG size ) @@ -1931,6 +2026,9 @@ static HRESULT write_type( struct writer *writer, WS_TYPE_MAPPING mapping, WS_TY case WS_UINT64_TYPE: return write_type_uint64( writer, mapping, desc, option, value, size ); + case WS_DATETIME_TYPE: + return write_type_datetime( writer, mapping, desc, option, value, size ); + case WS_GUID_TYPE: return write_type_guid( writer, mapping, desc, option, value, size ); diff --git a/include/webservices.h b/include/webservices.h index f09d15b..13fdaa7 100644 --- a/include/webservices.h +++ b/include/webservices.h @@ -58,6 +58,7 @@ typedef struct _WS_OPERATION_CONTEXT WS_OPERATION_CONTEXT; typedef struct _WS_CALL_PROPERTY WS_CALL_PROPERTY; typedef struct _WS_DOUBLE_DESCRIPTION WS_DOUBLE_DESCRIPTION; typedef struct _WS_DATETIME WS_DATETIME; +typedef struct _WS_XML_DATETIME_TEXT WS_XML_DATETIME_TEXT; typedef struct _WS_DATETIME_DESCRIPTION WS_DATETIME_DESCRIPTION; typedef struct _WS_GUID_DESCRIPTION WS_GUID_DESCRIPTION; typedef struct _WS_UNIQUE_ID_DESCRIPTION WS_UNIQUE_ID_DESCRIPTION; @@ -1106,6 +1107,11 @@ struct _WS_DATETIME_DESCRIPTION { WS_DATETIME maxValue; }; +struct _WS_XML_DATETIME_TEXT { + WS_XML_TEXT text; + WS_DATETIME value; +}; + typedef enum { WS_URL_HTTP_SCHEME_TYPE, WS_URL_HTTPS_SCHEME_TYPE, -- 2.1.4 From hans at codeweavers.com Tue Oct 4 06:28:35 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Tue, 4 Oct 2016 13:28:35 +0200 Subject: [2/3] webservices: Add support for reading WS_BYTES values. Message-ID: <1475580516-21147-4-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/reader.c | 157 +++++++++++++++++++++++++++++++++++++--- dlls/webservices/tests/reader.c | 22 ++++++ include/webservices.h | 13 ++++ 3 files changed, 180 insertions(+), 12 deletions(-) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index d106b18..8b9faf2 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -2468,6 +2468,78 @@ static HRESULT str_to_guid( const unsigned char *str, ULONG len, GUID *ret ) return S_OK; } +static inline unsigned char decode_char( unsigned char c ) +{ + if (c >= 'A' && c <= 'Z') return c - 'A'; + if (c >= 'a' && c <= 'z') return c - 'a' + 26; + if (c >= '0' && c <= '9') return c - '0' + 52; + if (c == '+') return 62; + if (c == '/') return 63; + return 64; +} + +static ULONG decode_base64( const unsigned char *base64, ULONG len, unsigned char *buf ) +{ + ULONG i = 0; + unsigned char c0, c1, c2, c3; + const unsigned char *p = base64; + + while (len > 4) + { + if ((c0 = decode_char( p[0] )) > 63) return 0; + if ((c1 = decode_char( p[1] )) > 63) return 0; + if ((c2 = decode_char( p[2] )) > 63) return 0; + if ((c3 = decode_char( p[3] )) > 63) return 0; + buf[i + 0] = (c0 << 2) | (c1 >> 4); + buf[i + 1] = (c1 << 4) | (c2 >> 2); + buf[i + 2] = (c2 << 6) | c3; + len -= 4; + i += 3; + p += 4; + } + if (p[2] == '=') + { + if ((c0 = decode_char( p[0] )) > 63) return 0; + if ((c1 = decode_char( p[1] )) > 63) return 0; + buf[i] = (c0 << 2) | (c1 >> 4); + i++; + } + else if (p[3] == '=') + { + if ((c0 = decode_char( p[0] )) > 63) return 0; + if ((c1 = decode_char( p[1] )) > 63) return 0; + if ((c2 = decode_char( p[2] )) > 63) return 0; + buf[i + 0] = (c0 << 2) | (c1 >> 4); + buf[i + 1] = (c1 << 4) | (c2 >> 2); + i += 2; + } + else + { + if ((c0 = decode_char( p[0] )) > 63) return 0; + if ((c1 = decode_char( p[1] )) > 63) return 0; + if ((c2 = decode_char( p[2] )) > 63) return 0; + if ((c3 = decode_char( p[3] )) > 63) return 0; + buf[i + 0] = (c0 << 2) | (c1 >> 4); + buf[i + 1] = (c1 << 4) | (c2 >> 2); + buf[i + 2] = (c2 << 6) | c3; + i += 3; + } + return i; +} + +static HRESULT str_to_bytes( const unsigned char *str, ULONG len, WS_HEAP *heap, WS_BYTES *ret ) +{ + const unsigned char *p = str; + + while (len && read_isspace( *p )) { p++; len--; } + while (len && read_isspace( p[len - 1] )) { len--; } + + if (len % 4) return WS_E_INVALID_FORMAT; + if (!(ret->bytes = ws_alloc( heap, len * 3 / 4 ))) return WS_E_QUOTA_EXCEEDED; + ret->length = decode_base64( p, len, ret->bytes ); + return S_OK; +} + static const int month_offsets[2][12] = { {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, @@ -3515,6 +3587,58 @@ static HRESULT read_type_guid( struct reader *reader, WS_TYPE_MAPPING mapping, return S_OK; } +static HRESULT read_type_bytes( struct reader *reader, WS_TYPE_MAPPING mapping, + const WS_XML_STRING *localname, const WS_XML_STRING *ns, + const WS_BYTES_DESCRIPTION *desc, WS_READ_OPTION option, + WS_HEAP *heap, void *ret, ULONG size ) +{ + WS_XML_UTF8_TEXT *utf8; + WS_BYTES val = {0}; + HRESULT hr; + BOOL found; + + if (desc) FIXME( "ignoring description\n" ); + + if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr; + if (found && (hr = str_to_bytes( utf8->value.bytes, utf8->value.length, heap, &val )) != S_OK) + return hr; + + switch (option) + { + case WS_READ_REQUIRED_VALUE: + if (!found) return WS_E_INVALID_FORMAT; + /* fall through */ + + case WS_READ_NILLABLE_VALUE: + if (size != sizeof(WS_BYTES)) return E_INVALIDARG; + *(WS_BYTES *)ret = val; + break; + + case WS_READ_REQUIRED_POINTER: + if (!found) return WS_E_INVALID_FORMAT; + /* fall through */ + + case WS_READ_OPTIONAL_POINTER: + case WS_READ_NILLABLE_POINTER: + { + WS_BYTES *heap_val = NULL; + if (size != sizeof(heap_val)) return E_INVALIDARG; + if (found) + { + if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED; + *heap_val = val; + } + *(WS_BYTES **)ret = heap_val; + break; + } + default: + FIXME( "read option %u not supported\n", option ); + return E_NOTIMPL; + } + + return S_OK; +} + static BOOL is_empty_text_node( const struct node *node ) { const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)node; @@ -3629,6 +3753,9 @@ ULONG get_type_size( WS_TYPE type, const WS_STRUCT_DESCRIPTION *desc ) case WS_WSZ_TYPE: return sizeof(WCHAR *); + case WS_BYTES_TYPE: + return sizeof(WS_BYTES); + case WS_STRUCT_TYPE: return desc->size; @@ -3659,10 +3786,11 @@ static WS_READ_OPTION get_field_read_option( WS_TYPE type, ULONG options ) case WS_UINT32_TYPE: case WS_UINT64_TYPE: case WS_DOUBLE_TYPE: - case WS_ENUM_TYPE: case WS_DATETIME_TYPE: case WS_GUID_TYPE: + case WS_BYTES_TYPE: case WS_STRUCT_TYPE: + case WS_ENUM_TYPE: if (options & (WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE)) return WS_READ_NILLABLE_VALUE; return WS_READ_REQUIRED_VALUE; @@ -3924,11 +4052,6 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP switch (type) { - case WS_STRUCT_TYPE: - if ((hr = read_type_struct( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK) - return hr; - break; - case WS_BOOL_TYPE: if ((hr = read_type_bool( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK) return hr; @@ -3979,23 +4102,33 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP return hr; break; + case WS_DATETIME_TYPE: + if ((hr = read_type_datetime( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK) + return hr; + break; + + case WS_GUID_TYPE: + if ((hr = read_type_guid( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK) + return hr; + break; + case WS_WSZ_TYPE: if ((hr = read_type_wsz( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK) return hr; break; - case WS_ENUM_TYPE: - if ((hr = read_type_enum( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK) + case WS_BYTES_TYPE: + if ((hr = read_type_bytes( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK) return hr; break; - case WS_DATETIME_TYPE: - if ((hr = read_type_datetime( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK) + case WS_STRUCT_TYPE: + if ((hr = read_type_struct( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK) return hr; break; - case WS_GUID_TYPE: - if ((hr = read_type_guid( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK) + case WS_ENUM_TYPE: + if ((hr = read_type_enum( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK) return hr; break; diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index 9d3cd75..06c18b2 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -1339,6 +1339,7 @@ static void test_WsReadType(void) UINT32 val_uint32; UINT64 val_uint64; GUID val_guid; + WS_BYTES val_bytes; hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL ); ok( hr == S_OK, "got %08x\n", hr ); @@ -1608,6 +1609,27 @@ static void test_WsReadType(void) ok( hr == S_OK, "got %08x\n", hr ); ok( IsEqualGUID( &val_guid, &guid2 ), "wrong guid\n" ); + memset( &val_bytes, 0, sizeof(val_bytes) ); + prepare_type_test( reader, "dGVzdA==", sizeof("dGVzdA==") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_bytes.length == 4, "got %u\n", val_bytes.length ); + ok( !memcmp( val_bytes.bytes, "test", 4 ), "wrong data\n" ); + + memset( &val_bytes, 0, sizeof(val_bytes) ); + prepare_type_test( reader, " dGVzdA== ", sizeof(" dGVzdA== ") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_bytes.length == 4, "got %u\n", val_bytes.length ); + ok( !memcmp( val_bytes.bytes, "test", 4 ), "wrong data\n" ); + + prepare_type_test( reader, "dGVzdA===", sizeof("dGVzdA===") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_bytes, sizeof(val_bytes), NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + WsFreeReader( reader ); WsFreeHeap( heap ); } diff --git a/include/webservices.h b/include/webservices.h index 13fdaa7..f1d34c4 100644 --- a/include/webservices.h +++ b/include/webservices.h @@ -59,9 +59,11 @@ typedef struct _WS_CALL_PROPERTY WS_CALL_PROPERTY; typedef struct _WS_DOUBLE_DESCRIPTION WS_DOUBLE_DESCRIPTION; typedef struct _WS_DATETIME WS_DATETIME; typedef struct _WS_XML_DATETIME_TEXT WS_XML_DATETIME_TEXT; +typedef struct _WS_XML_BASE64_TEXT WS_XML_BASE64_TEXT; typedef struct _WS_DATETIME_DESCRIPTION WS_DATETIME_DESCRIPTION; typedef struct _WS_GUID_DESCRIPTION WS_GUID_DESCRIPTION; typedef struct _WS_UNIQUE_ID_DESCRIPTION WS_UNIQUE_ID_DESCRIPTION; +typedef struct _WS_BYTES_DESCRIPTION WS_BYTES_DESCRIPTION; typedef struct _WS_URL WS_URL; typedef struct _WS_HTTP_URL WS_HTTP_URL; typedef struct _WS_HTTPS_URL WS_HTTPS_URL; @@ -426,6 +428,11 @@ struct _WS_UNIQUE_ID_DESCRIPTION { ULONG maxCharCount; }; +struct _WS_BYTES_DESCRIPTION { + ULONG minByteCount; + ULONG maxByteCount; +}; + typedef enum { WS_TYPE_ATTRIBUTE_FIELD_MAPPING, WS_ATTRIBUTE_FIELD_MAPPING, @@ -1112,6 +1119,12 @@ struct _WS_XML_DATETIME_TEXT { WS_DATETIME value; }; +struct _WS_XML_BASE64_TEXT { + WS_XML_TEXT text; + BYTE *bytes; + ULONG length; +}; + typedef enum { WS_URL_HTTP_SCHEME_TYPE, WS_URL_HTTPS_SCHEME_TYPE, -- 2.1.4 From hans at codeweavers.com Tue Oct 4 06:28:36 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Tue, 4 Oct 2016 13:28:36 +0200 Subject: [3/3] webservices: Add support for writing WS_BYTES values. Message-ID: <1475580516-21147-5-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/tests/writer.c | 100 ++++++++++++++++++++++------------------ dlls/webservices/writer.c | 75 ++++++++++++++++++++++++++++-- 2 files changed, 127 insertions(+), 48 deletions(-) diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index c817615..3bed673 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -574,6 +574,17 @@ static void test_WsWriteType(void) WsFreeWriter( writer ); } +static void prepare_basic_type_test( WS_XML_WRITER *writer ) +{ + WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL}; + HRESULT hr; + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); +} + static void test_basic_type(void) { static WCHAR testW[] = {'t','e','s','t',0}; @@ -583,6 +594,7 @@ static void test_basic_type(void) GUID guid; WCHAR *str; WS_STRING string; + WS_BYTES bytes; ULONG i; static const struct { @@ -615,12 +627,7 @@ static void test_basic_type(void) /* element content type mapping */ for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - hr = set_output( writer ); - ok( hr == S_OK, "got %08x\n", hr ); - - hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - + prepare_basic_type_test( writer ); hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, tests[i].type, NULL, WS_WRITE_REQUIRED_VALUE, &tests[i].val, tests[i].size, NULL ); ok( hr == S_OK, "%u: got %08x\n", i, hr ); @@ -635,12 +642,7 @@ static void test_basic_type(void) { const INT64 *ptr = &tests[i].val; - hr = set_output( writer ); - ok( hr == S_OK, "got %08x\n", hr ); - - hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - + prepare_basic_type_test( writer ); hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, tests[i].type, NULL, WS_WRITE_REQUIRED_POINTER, &ptr, sizeof(ptr), NULL ); ok( hr == S_OK, "%u: got %08x\n", i, hr ); @@ -653,12 +655,7 @@ static void test_basic_type(void) /* attribute type mapping */ for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - hr = set_output( writer ); - ok( hr == S_OK, "got %08x\n", hr ); - - hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - + prepare_basic_type_test( writer ); hr = WsWriteStartAttribute( writer, NULL, &localname, &ns, FALSE, NULL ); ok( hr == S_OK, "got %08x\n", hr ); @@ -674,67 +671,80 @@ static void test_basic_type(void) check_output( writer, tests[i].result2, __LINE__ ); } - hr = set_output( writer ); - ok( hr == S_OK, "got %08x\n", hr ); - - hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - + prepare_basic_type_test( writer ); memset( &guid, 0, sizeof(guid) ); hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_GUID_TYPE, NULL, WS_WRITE_REQUIRED_VALUE, &guid, sizeof(guid), NULL ); ok( hr == S_OK, "got %08x\n", hr ); - hr = WsWriteEndElement( writer, NULL ); ok( hr == S_OK, "got %08x\n", hr ); check_output( writer, "00000000-0000-0000-0000-000000000000", __LINE__ ); - hr = set_output( writer ); - ok( hr == S_OK, "got %08x\n", hr ); - - hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - + prepare_basic_type_test( writer ); string.chars = testW; string.length = 4; hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_STRING_TYPE, NULL, WS_WRITE_REQUIRED_VALUE, &string, sizeof(string), NULL ); ok( hr == S_OK, "got %08x\n", hr ); - hr = WsWriteEndElement( writer, NULL ); ok( hr == S_OK, "got %08x\n", hr ); check_output( writer, "test", __LINE__ ); - hr = set_output( writer ); - ok( hr == S_OK, "got %08x\n", hr ); - - hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); - ok( hr == S_OK, "got %08x\n", hr ); - + prepare_basic_type_test( writer ); str = testW; hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL, WS_WRITE_REQUIRED_POINTER, &str, sizeof(str), NULL ); ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "test", __LINE__ ); + prepare_basic_type_test( writer ); + xmlstr.bytes = (BYTE *)"test"; + xmlstr.length = 4; + hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_XML_STRING_TYPE, NULL, WS_WRITE_REQUIRED_VALUE, + &xmlstr, sizeof(xmlstr), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); hr = WsWriteEndElement( writer, NULL ); ok( hr == S_OK, "got %08x\n", hr ); check_output( writer, "test", __LINE__ ); - hr = set_output( writer ); + prepare_basic_type_test( writer ); + bytes.bytes = (BYTE *)"test"; + bytes.length = 4; + hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL, WS_WRITE_REQUIRED_VALUE, + &bytes, sizeof(bytes), NULL ); ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "dGVzdA==", __LINE__ ); - hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + prepare_basic_type_test( writer ); + bytes.length = 0; + hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL, WS_WRITE_REQUIRED_VALUE, + &bytes, sizeof(bytes), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteEndElement( writer, NULL ); ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "", __LINE__ ); - xmlstr.bytes = (BYTE *)"test"; - xmlstr.length = 4; - hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_XML_STRING_TYPE, NULL, WS_WRITE_REQUIRED_VALUE, - &xmlstr, sizeof(xmlstr), NULL ); + prepare_basic_type_test( writer ); + bytes.bytes = NULL; + hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL, WS_WRITE_REQUIRED_VALUE, + &bytes, sizeof(bytes), NULL ); ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "", __LINE__ ); + prepare_basic_type_test( writer ); + hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_BYTES_TYPE, NULL, WS_WRITE_NILLABLE_VALUE, + &bytes, sizeof(bytes), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); hr = WsWriteEndElement( writer, NULL ); ok( hr == S_OK, "got %08x\n", hr ); - check_output( writer, "test", __LINE__ ); + check_output( writer, "", + __LINE__ ); WsFreeWriter( writer ); } diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 7a818eb..619ec2b 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -1265,6 +1265,38 @@ static ULONG format_urn( const GUID *ptr, unsigned char *buf ) ptr->Data4[4], ptr->Data4[5], ptr->Data4[6], ptr->Data4[7] ); } +static ULONG encode_base64( const unsigned char *bin, ULONG len, unsigned char *buf ) +{ + static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + ULONG i = 0, x; + + while (len > 0) + { + buf[i++] = base64[(bin[0] & 0xfc) >> 2]; + x = (bin[0] & 3) << 4; + if (len == 1) + { + buf[i++] = base64[x]; + buf[i++] = '='; + buf[i++] = '='; + break; + } + buf[i++] = base64[x | ((bin[1] & 0xf0) >> 4)]; + x = (bin[1] & 0x0f) << 2; + if (len == 2) + { + buf[i++] = base64[x]; + buf[i++] = '='; + break; + } + buf[i++] = base64[x | ((bin[2] & 0xc0) >> 6)]; + buf[i++] = base64[bin[2] & 0x3f]; + bin += 3; + len -= 3; + } + return i; +} + static HRESULT text_to_utf8text( const WS_XML_TEXT *text, WS_XML_UTF8_TEXT **ret ) { switch (text->textType) @@ -1287,6 +1319,14 @@ static HRESULT text_to_utf8text( const WS_XML_TEXT *text, WS_XML_UTF8_TEXT **ret WideCharToMultiByte( CP_UTF8, 0, str, len, (char *)(*ret)->value.bytes, (*ret)->value.length, NULL, NULL ); return S_OK; } + case WS_XML_TEXT_TYPE_BASE64: + { + const WS_XML_BASE64_TEXT *base64 = (const WS_XML_BASE64_TEXT *)text; + ULONG len = ((4 * base64->length / 3) + 3) & ~3; + if (!(*ret = alloc_utf8_text( NULL, len ))) return E_OUTOFMEMORY; + (*ret)->value.length = encode_base64( base64->bytes, base64->length, (*ret)->value.bytes ); + return S_OK; + } case WS_XML_TEXT_TYPE_BOOL: { const WS_XML_BOOL_TEXT *bool_text = (const WS_XML_BOOL_TEXT *)text; @@ -1837,6 +1877,32 @@ static HRESULT write_type_wsz( struct writer *writer, WS_TYPE_MAPPING mapping, return write_type_text( writer, mapping, &utf16.text ); } +static HRESULT write_type_bytes( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_BYTES_DESCRIPTION *desc, WS_WRITE_OPTION option, + const void *value, ULONG size ) +{ + WS_XML_BASE64_TEXT base64; + const WS_BYTES *ptr; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + + if (!option) return E_INVALIDARG; + if ((hr = get_value_ptr( option, value, size, sizeof(WS_BYTES), (const void **)&ptr )) != S_OK) return hr; + if ((option == WS_WRITE_NILLABLE_VALUE && is_nil_value( value, size )) || + (option == WS_WRITE_NILLABLE_POINTER && !ptr)) return write_add_nil_attribute( writer ); + if (!ptr->length) return S_OK; + + base64.text.textType = WS_XML_TEXT_TYPE_BASE64; + base64.bytes = ptr->bytes; + base64.length = ptr->length; + return write_type_text( writer, mapping, &base64.text ); +} + static HRESULT write_type_xml_string( struct writer *writer, WS_TYPE_MAPPING mapping, const WS_XML_STRING_DESCRIPTION *desc, WS_WRITE_OPTION option, const void *value, ULONG size ) @@ -1996,9 +2062,6 @@ static HRESULT write_type( struct writer *writer, WS_TYPE_MAPPING mapping, WS_TY { switch (type) { - case WS_STRUCT_TYPE: - return write_type_struct( writer, mapping, desc, option, value, size ); - case WS_BOOL_TYPE: return write_type_bool( writer, mapping, desc, option, value, size ); @@ -2038,9 +2101,15 @@ static HRESULT write_type( struct writer *writer, WS_TYPE_MAPPING mapping, WS_TY case WS_WSZ_TYPE: return write_type_wsz( writer, mapping, desc, option, value, size ); + case WS_BYTES_TYPE: + return write_type_bytes( writer, mapping, desc, option, value, size ); + case WS_XML_STRING_TYPE: return write_type_xml_string( writer, mapping, desc, option, value, size ); + case WS_STRUCT_TYPE: + return write_type_struct( writer, mapping, desc, option, value, size ); + default: FIXME( "type %u not supported\n", type ); return E_NOTIMPL; -- 2.1.4 From huw at codeweavers.com Tue Oct 4 07:07:31 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 4 Oct 2016 13:07:31 +0100 Subject: [PATCH 1/7] riched20: Set the end-of-paragraph run width to that of a space. Message-ID: <1475582857-95211-1-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/run.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index 778a952..984f8f5 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -611,17 +611,16 @@ SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run *run, i int startx, int *pAscent, int *pDescent) { SIZE size; - int nMaxLen = run->len; + WCHAR spaceW[] = {' ',0}; - if (nLen>nMaxLen) - nLen = nMaxLen; + nLen = min( nLen, run->len ); - /* FIXME the following call also ensures that TEXTMETRIC structure is filled - * this is wasteful for MERF_NONTEXT runs, but that shouldn't matter - * in practice - */ - - if (para->nFlags & MEPF_COMPLEX) + if (run->nFlags & MERF_ENDPARA) + { + nLen = min( nLen, 1 ); + ME_GetTextExtent(c, spaceW, nLen, run->style, &size); + } + else if (para->nFlags & MEPF_COMPLEX) { size.cx = run->nWidth; } -- 2.8.2 From huw at codeweavers.com Tue Oct 4 07:07:33 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 4 Oct 2016 13:07:33 +0100 Subject: [PATCH 3/7] riched20: Allow selecting the final end-of-paragraph when using the right arrow key. Message-ID: <1475582857-95211-3-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/caret.c | 15 ++++++++------- dlls/riched20/editor.c | 6 +++--- dlls/riched20/editor.h | 2 +- dlls/riched20/richole.c | 2 +- dlls/riched20/table.c | 2 +- dlls/riched20/undo.c | 2 +- dlls/riched20/writer.c | 4 +--- 7 files changed, 16 insertions(+), 17 deletions(-) diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index 279bdcd..b137c5f 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -200,7 +200,7 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to) ME_CursorFromCharOfs(editor, from, &editor->pCursors[1]); editor->pCursors[0] = editor->pCursors[1]; - ME_MoveCursorChars(editor, &editor->pCursors[0], to - from); + ME_MoveCursorChars(editor, &editor->pCursors[0], to - from, FALSE); /* Selection is not allowed in the middle of an end paragraph run. */ if (editor->pCursors[1].pRun->member.run.nFlags & MERF_ENDPARA) editor->pCursors[1].nOffset = 0; @@ -627,10 +627,11 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, } /* Move the cursor nRelOfs characters (either forwards or backwards) + * If final_eop is TRUE, allow moving the cursor to the end of the final eop. * * returns the actual number of characters moved. **/ -int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs) +int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BOOL final_eop) { cursor->nOffset += nRelOfs; if (cursor->nOffset < 0) @@ -682,11 +683,11 @@ int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs) return nRelOfs; } - if (new_offset >= ME_GetTextLength(editor)) + if (new_offset >= ME_GetTextLength(editor) + (final_eop ? 1 : 0)) { /* new offset at the end of the text */ - ME_SetCursorToEnd(editor, cursor, FALSE); - nRelOfs -= new_offset - ME_GetTextLength(editor); + ME_SetCursorToEnd(editor, cursor, final_eop); + nRelOfs -= new_offset - (ME_GetTextLength(editor) + (final_eop ? 1 : 0)); return nRelOfs; } @@ -1547,14 +1548,14 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl) if (ctrl) success = ME_MoveCursorWords(editor, &tmp_curs, -1); else - success = ME_MoveCursorChars(editor, &tmp_curs, -1); + success = ME_MoveCursorChars(editor, &tmp_curs, -1, extend); break; case VK_RIGHT: editor->bCaretAtEnd = FALSE; if (ctrl) success = ME_MoveCursorWords(editor, &tmp_curs, +1); else - success = ME_MoveCursorChars(editor, &tmp_curs, +1); + success = ME_MoveCursorChars(editor, &tmp_curs, +1, extend); break; case VK_UP: ME_MoveCursorLines(editor, &tmp_curs, -1); diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 97c2d59..4adc74f 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -1650,7 +1650,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre int linebreakSize = editor->bEmulateVersion10 ? 2 : 1; ME_Cursor linebreakCursor = *selEnd; - ME_MoveCursorChars(editor, &linebreakCursor, -linebreakSize); + ME_MoveCursorChars(editor, &linebreakCursor, -linebreakSize, FALSE); ME_GetTextW(editor, lastchar, 2, &linebreakCursor, linebreakSize, FALSE, FALSE); if (lastchar[0] == '\r' && (lastchar[1] == '\n' || lastchar[1] == '\0')) { ME_InternalDeleteText(editor, &linebreakCursor, linebreakSize, FALSE); @@ -1805,7 +1805,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH { ME_CursorFromCharOfs(editor, nMin - 1, &cursor); wLastChar = *get_text( &cursor.pRun->member.run, cursor.nOffset ); - ME_MoveCursorChars(editor, &cursor, 1); + ME_MoveCursorChars(editor, &cursor, 1, FALSE); } else { ME_CursorFromCharOfs(editor, nMin, &cursor); } @@ -1881,7 +1881,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH { ME_CursorFromCharOfs(editor, nMax + 1, &cursor); wLastChar = *get_text( &cursor.pRun->member.run, cursor.nOffset ); - ME_MoveCursorChars(editor, &cursor, -1); + ME_MoveCursorChars(editor, &cursor, -1, FALSE); } else { ME_CursorFromCharOfs(editor, nMax, &cursor); } diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index cc1654a..c62b3a4 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -178,7 +178,7 @@ BOOL ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars) DECLS void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, const WCHAR *str, int len, ME_Style *style) DECLSPEC_HIDDEN; void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor) DECLSPEC_HIDDEN; -int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs) DECLSPEC_HIDDEN; +int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BOOL final_eop) DECLSPEC_HIDDEN; BOOL ME_ArrowKey(ME_TextEditor *ed, int nVKey, BOOL extend, BOOL ctrl) DECLSPEC_HIDDEN; int ME_GetCursorOfs(const ME_Cursor *cursor) DECLSPEC_HIDDEN; diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c index 77e7b57..c5f0441 100644 --- a/dlls/riched20/richole.c +++ b/dlls/riched20/richole.c @@ -451,7 +451,7 @@ static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, ME_CursorFromCharOfs(reole->editor, pos, &from); to = from; - ME_MoveCursorChars(reole->editor, &to, 1); + ME_MoveCursorChars(reole->editor, &to, 1, FALSE); ME_GetCharFormat(reole->editor, &from, &to, &fmt); switch (propid) diff --git a/dlls/riched20/table.c b/dlls/riched20/table.c index c22f92a..b834bc7 100644 --- a/dlls/riched20/table.c +++ b/dlls/riched20/table.c @@ -291,7 +291,7 @@ void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, ME_Cursor *c, int *nC ME_DisplayItem *this_para = c->pPara; ME_DisplayItem *end_para; - ME_MoveCursorChars(editor, &c2, *nChars); + ME_MoveCursorChars(editor, &c2, *nChars, FALSE); end_para = c2.pPara; if (c2.pRun->member.run.nFlags & MERF_ENDPARA) { /* End offset might be in the middle of the end paragraph run. diff --git a/dlls/riched20/undo.c b/dlls/riched20/undo.c index 7a8c333..582f888 100644 --- a/dlls/riched20/undo.c +++ b/dlls/riched20/undo.c @@ -349,7 +349,7 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, struct undo_item *undo) ME_Cursor start, end; ME_CursorFromCharOfs(editor, undo->u.set_char_fmt.pos, &start); end = start; - ME_MoveCursorChars(editor, &end, undo->u.set_char_fmt.len); + ME_MoveCursorChars(editor, &end, undo->u.set_char_fmt.len, FALSE); ME_SetCharFormat(editor, &start, &end, &undo->u.set_char_fmt.fmt); break; } diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index a3eaffe..cff76ad 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -883,9 +883,7 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, ME_Cursor endCur = cursor; int actual_chars; - actual_chars = ME_MoveCursorChars(editor, &endCur, nChars); - /* Include the final \r which MoveCursorChars will ignore. */ - if (actual_chars != nChars) endCur.nOffset++; + actual_chars = ME_MoveCursorChars(editor, &endCur, nChars, TRUE); if (!ME_StreamOutRTFHeader(pStream, dwFormat)) return FALSE; -- 2.8.2 From huw at codeweavers.com Tue Oct 4 07:07:32 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 4 Oct 2016 13:07:32 +0100 Subject: [PATCH 2/7] riched20: Add an option to move the cursor to after the final end-of-paragraph. Message-ID: <1475582857-95211-2-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/caret.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index e5c60a0..279bdcd 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -31,11 +31,11 @@ void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor) cursor->nOffset = 0; } -static void ME_SetCursorToEnd(ME_TextEditor *editor, ME_Cursor *cursor) +static void ME_SetCursorToEnd(ME_TextEditor *editor, ME_Cursor *cursor, BOOL final_eop) { cursor->pPara = editor->pBuffer->pLast->member.para.prev_para; cursor->pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun); - cursor->nOffset = 0; + cursor->nOffset = final_eop ? cursor->pRun->member.run.len : 0; } @@ -83,7 +83,7 @@ int ME_GetSelection(ME_TextEditor *editor, ME_Cursor **from, ME_Cursor **to) int ME_GetTextLength(ME_TextEditor *editor) { ME_Cursor cursor; - ME_SetCursorToEnd(editor, &cursor); + ME_SetCursorToEnd(editor, &cursor, FALSE); return ME_GetCursorOfs(&cursor); } @@ -138,8 +138,7 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to) if (from == 0 && to == -1) { ME_SetCursorToStart(editor, &editor->pCursors[1]); - ME_SetCursorToEnd(editor, &editor->pCursors[0]); - editor->pCursors[0].nOffset = editor->pCursors[0].pRun->member.run.len; + ME_SetCursorToEnd(editor, &editor->pCursors[0], TRUE); ME_InvalidateSelection(editor); return len + 1; } @@ -193,7 +192,7 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to) if (selectionEnd) { - ME_SetCursorToEnd(editor, &editor->pCursors[0]); + ME_SetCursorToEnd(editor, &editor->pCursors[0], FALSE); editor->pCursors[1] = editor->pCursors[0]; ME_InvalidateSelection(editor); return len; @@ -686,7 +685,7 @@ int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs) if (new_offset >= ME_GetTextLength(editor)) { /* new offset at the end of the text */ - ME_SetCursorToEnd(editor, cursor); + ME_SetCursorToEnd(editor, cursor, FALSE); nRelOfs -= new_offset - ME_GetTextLength(editor); return nRelOfs; } @@ -859,7 +858,7 @@ ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType) /* Select everything with cursor anchored from the start of the text */ editor->nSelectionType = stDocument; ME_SetCursorToStart(editor, &editor->pCursors[1]); - ME_SetCursorToEnd(editor, &editor->pCursors[0]); + ME_SetCursorToEnd(editor, &editor->pCursors[0], FALSE); break; default: assert(0); } @@ -1383,7 +1382,7 @@ static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor) if (editor->vert_si.nPos >= y - editor->sizeWindow.cy) { - ME_SetCursorToEnd(editor, pCursor); + ME_SetCursorToEnd(editor, pCursor, FALSE); editor->bCaretAtEnd = FALSE; } else { ME_DisplayItem *pRun = pCursor->pRun; @@ -1480,7 +1479,7 @@ static void ME_ArrowEnd(ME_TextEditor *editor, ME_Cursor *pCursor) static void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor) { - ME_SetCursorToEnd(editor, pCursor); + ME_SetCursorToEnd(editor, pCursor, FALSE); editor->bCaretAtEnd = FALSE; } -- 2.8.2 From huw at codeweavers.com Tue Oct 4 07:07:34 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 4 Oct 2016 13:07:34 +0100 Subject: [PATCH 4/7] riched20: Allow selecting to the start / end when using the up / down arrow keys. Message-ID: <1475582857-95211-4-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/caret.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index b137c5f..74239af 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -1237,7 +1237,7 @@ static int ME_GetXForArrow(ME_TextEditor *editor, ME_Cursor *pCursor) static void -ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs) +ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs, BOOL extend) { ME_DisplayItem *pRun = pCursor->pRun; ME_DisplayItem *pOldPara = pCursor->pPara; @@ -1255,8 +1255,12 @@ ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs) assert(pItem); /* start of the previous row */ pItem = ME_FindItemBack(pItem, diStartRow); - if (!pItem) - return; /* row not found - ignore */ + if (!pItem) /* row not found */ + { + if (extend) + ME_SetCursorToStart(editor, pCursor); + return; + } pNewPara = ME_GetParagraph(pItem); if (pOldPara->member.para.nFlags & MEPF_ROWEND || (pOldPara->member.para.pCell && @@ -1282,8 +1286,12 @@ ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs) { /* start of the next row */ pItem = ME_FindItemFwd(pRun, diStartRow); - if (!pItem) - return; /* row not found - ignore */ + if (!pItem) /* row not found */ + { + if (extend) + ME_SetCursorToEnd(editor, pCursor, TRUE); + return; + } pNewPara = ME_GetParagraph(pItem); if (pOldPara->member.para.nFlags & MEPF_ROWSTART || (pOldPara->member.para.pCell && @@ -1558,10 +1566,10 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl) success = ME_MoveCursorChars(editor, &tmp_curs, +1, extend); break; case VK_UP: - ME_MoveCursorLines(editor, &tmp_curs, -1); + ME_MoveCursorLines(editor, &tmp_curs, -1, extend); break; case VK_DOWN: - ME_MoveCursorLines(editor, &tmp_curs, +1); + ME_MoveCursorLines(editor, &tmp_curs, +1, extend); break; case VK_PRIOR: ME_ArrowPageUp(editor, &tmp_curs); -- 2.8.2 From huw at codeweavers.com Tue Oct 4 07:07:35 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 4 Oct 2016 13:07:35 +0100 Subject: [PATCH 5/7] riched20: Allow selecting the final end-of-paragraph when using the mouse. Message-ID: <1475582857-95211-5-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/caret.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index 74239af..1dacdfa 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -961,11 +961,13 @@ static BOOL ME_FindRunInRow(ME_TextEditor *editor, ME_DisplayItem *pRow, * x & y are pixel positions in virtual coordinates into the rich edit control, * so client coordinates must first be adjusted by the scroll position. * + * If final_eop is TRUE consider the final end-of-paragraph. + * * returns TRUE if the result was exactly under the cursor, otherwise returns * FALSE, and result is set to the closest position to the coordinates. */ static BOOL ME_FindPixelPos(ME_TextEditor *editor, int x, int y, - ME_Cursor *result, BOOL *is_eol) + ME_Cursor *result, BOOL *is_eol, BOOL final_eop) { ME_DisplayItem *p = editor->pBuffer->pFirst->member.para.next_para; BOOL isExact = TRUE; @@ -1001,7 +1003,7 @@ static BOOL ME_FindPixelPos(ME_TextEditor *editor, int x, int y, if (!pp) break; p = pp; } - if (p == editor->pBuffer->pLast) + if (p == editor->pBuffer->pLast && !final_eop) { /* The position is below the last paragraph, so the last row will be used * rather than the end of the text, so the x position will be used to @@ -1016,10 +1018,7 @@ static BOOL ME_FindPixelPos(ME_TextEditor *editor, int x, int y, if( p->type == diStartRow ) return ME_FindRunInRow( editor, p, x, result, is_eol ) && isExact; - result->pRun = ME_FindItemBack(p, diRun); - result->pPara = ME_GetParagraph(result->pRun); - result->nOffset = 0; - assert(result->pRun->member.run.nFlags & MERF_ENDPARA); + ME_SetCursorToEnd(editor, result, TRUE); return FALSE; } @@ -1047,7 +1046,7 @@ BOOL ME_CharFromPos(ME_TextEditor *editor, int x, int y, } x += editor->horz_si.nPos; y += editor->vert_si.nPos; - bResult = ME_FindPixelPos(editor, x, y, cursor, NULL); + bResult = ME_FindPixelPos(editor, x, y, cursor, NULL, FALSE); if (isExact) *isExact = bResult; return TRUE; } @@ -1130,7 +1129,7 @@ void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum) is_selection = ME_IsSelection(editor); is_shift = GetKeyState(VK_SHIFT) < 0; - ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd); + ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd, FALSE); if (x >= editor->rcFormat.left || is_shift) { @@ -1190,7 +1189,7 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y) tmp_cursor = editor->pCursors[0]; /* FIXME: do something with the return value of ME_FindPixelPos */ - ME_FindPixelPos(editor, x, y, &tmp_cursor, &editor->bCaretAtEnd); + ME_FindPixelPos(editor, x, y, &tmp_cursor, &editor->bCaretAtEnd, TRUE); ME_InvalidateSelection(editor); editor->pCursors[0] = tmp_cursor; -- 2.8.2 From huw at codeweavers.com Tue Oct 4 07:07:36 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 4 Oct 2016 13:07:36 +0100 Subject: [PATCH 6/7] riched20: Clearing the insert style should not depend on the event mask. Message-ID: <1475582857-95211-6-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/caret.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index 1dacdfa..a47930f 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -1515,9 +1515,6 @@ void ME_SendSelChange(ME_TextEditor *editor) { SELCHANGE sc; - if (!(editor->nEventMask & ENM_SELCHANGE)) - return; - sc.nmhdr.hwndFrom = NULL; sc.nmhdr.idFrom = 0; sc.nmhdr.code = EN_SELCHANGE; @@ -1527,16 +1524,21 @@ void ME_SendSelChange(ME_TextEditor *editor) sc.seltyp |= SEL_TEXT; if (sc.chrg.cpMin < sc.chrg.cpMax+1) /* what were RICHEDIT authors thinking ? */ sc.seltyp |= SEL_MULTICHAR; - TRACE("cpMin=%d cpMax=%d seltyp=%d (%s %s)\n", - sc.chrg.cpMin, sc.chrg.cpMax, sc.seltyp, - (sc.seltyp & SEL_TEXT) ? "SEL_TEXT" : "", - (sc.seltyp & SEL_MULTICHAR) ? "SEL_MULTICHAR" : ""); + if (sc.chrg.cpMin != editor->notified_cr.cpMin || sc.chrg.cpMax != editor->notified_cr.cpMax) { ME_ClearTempStyle(editor); editor->notified_cr = sc.chrg; - ITextHost_TxNotify(editor->texthost, sc.nmhdr.code, &sc); + + if (editor->nEventMask & ENM_SELCHANGE) + { + TRACE("cpMin=%d cpMax=%d seltyp=%d (%s %s)\n", + sc.chrg.cpMin, sc.chrg.cpMax, sc.seltyp, + (sc.seltyp & SEL_TEXT) ? "SEL_TEXT" : "", + (sc.seltyp & SEL_MULTICHAR) ? "SEL_MULTICHAR" : ""); + ITextHost_TxNotify(editor->texthost, sc.nmhdr.code, &sc); + } } } -- 2.8.2 From huw at codeweavers.com Tue Oct 4 07:07:37 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 4 Oct 2016 13:07:37 +0100 Subject: [PATCH 7/7] riched20: Move the wrap context struct into wrap.c . Message-ID: <1475582857-95211-7-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/editstr.h | 15 --------------- dlls/riched20/wrap.c | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index 261a701..35555a9 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -460,19 +460,4 @@ typedef struct tagME_Context ME_TextEditor *editor; } ME_Context; -typedef struct tagME_WrapContext -{ - ME_Style *style; - ME_Context *context; - int nLeftMargin, nRightMargin, nFirstMargin; - int nAvailWidth; - int nRow; - POINT pt; - BOOL bOverflown, bWordWrap; - ME_DisplayItem *pPara; - ME_DisplayItem *pRowStart; - - ME_DisplayItem *pLastSplittableRun; -} ME_WrapContext; - #endif diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index 195eb8d..24a7b16 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -33,6 +33,20 @@ WINE_DECLARE_DEBUG_CHANNEL(richedit_check); * - no tabs */ +typedef struct tagME_WrapContext +{ + ME_Style *style; + ME_Context *context; + int nLeftMargin, nRightMargin, nFirstMargin; + int nAvailWidth; + int nRow; + POINT pt; + BOOL bOverflown, bWordWrap; + ME_DisplayItem *pPara; + ME_DisplayItem *pRowStart; + + ME_DisplayItem *pLastSplittableRun; +} ME_WrapContext; static BOOL get_run_glyph_buffers( ME_Run *run ) { -- 2.8.2 From sebastian at fds-team.de Tue Oct 4 08:27:50 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Tue, 4 Oct 2016 15:27:50 +0200 Subject: [PATCH v2] hidclass.sys: minidriver handling for IRP_MN_REMOVE_DEVICE finished the IRP In-Reply-To: <70bc7a83-81fb-ebf1-d26c-32c997db4933@codeweavers.com> References: <70bc7a83-81fb-ebf1-d26c-32c997db4933@codeweavers.com> Message-ID: <2a8f35b0-50bc-125f-f86b-06867efd30cd@fds-team.de> On 04.10.2016 12:35, Aric Stewart wrote: > v2: remove unnecessary break > > Signed-off-by: Aric Stewart > --- > dlls/hidclass.sys/pnp.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > Signed-off-by: Sebastian Lackner From alexhenrie24 at gmail.com Tue Oct 4 10:22:00 2016 From: alexhenrie24 at gmail.com (Alex Henrie) Date: Tue, 4 Oct 2016 09:22:00 -0600 Subject: [PATCH v2] msinfo32: Display an About dialog when the program is run. Message-ID: <20161004152200.2603-1-alexhenrie24@gmail.com> Cc: Hugh McMaster Cc: Austin English Fixes https://bugs.winehq.org/show_bug.cgi?id=41430 An About dialog displays the most important piece of information (the Wine version), and we were going to have to add one to this program eventually anyway. Signed-off-by: Alex Henrie --- programs/msinfo32/Makefile.in | 3 +++ programs/msinfo32/main.c | 8 ++++++++ programs/msinfo32/msinfo32.rc | 24 ++++++++++++++++++++++++ programs/msinfo32/resource.h | 19 +++++++++++++++++++ 4 files changed, 54 insertions(+) create mode 100644 programs/msinfo32/msinfo32.rc create mode 100644 programs/msinfo32/resource.h diff --git a/programs/msinfo32/Makefile.in b/programs/msinfo32/Makefile.in index e958c27..d752c91 100644 --- a/programs/msinfo32/Makefile.in +++ b/programs/msinfo32/Makefile.in @@ -1,5 +1,8 @@ MODULE = msinfo32.exe APPMODE = -mwindows -municode +IMPORTS = shell32 user32 C_SRCS = \ main.c + +RC_SRCS = msinfo32.rc diff --git a/programs/msinfo32/main.c b/programs/msinfo32/main.c index 77bb927..1f213bd 100644 --- a/programs/msinfo32/main.c +++ b/programs/msinfo32/main.c @@ -16,12 +16,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include +#include + #include "wine/debug.h" +#include "resource.h" WINE_DEFAULT_DEBUG_CHANNEL(msinfo); int wmain(int argc, WCHAR *argv[]) { + WCHAR systemInfo[64]; int i; WINE_FIXME("stub:"); @@ -29,5 +34,8 @@ int wmain(int argc, WCHAR *argv[]) WINE_FIXME(" %s", wine_dbgstr_w(argv[i])); WINE_FIXME("\n"); + LoadStringW(GetModuleHandleW(NULL), STRING_SYSTEM_INFO, systemInfo, sizeof(systemInfo)/sizeof(WCHAR)); + ShellAboutW(NULL, systemInfo, NULL, NULL); + return 0; } diff --git a/programs/msinfo32/msinfo32.rc b/programs/msinfo32/msinfo32.rc new file mode 100644 index 0000000..ce4ab62 --- /dev/null +++ b/programs/msinfo32/msinfo32.rc @@ -0,0 +1,24 @@ +/* + * Copyright 2016 Alex Henrie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "resource.h" + +STRINGTABLE +{ + STRING_SYSTEM_INFO, "System Information" +} diff --git a/programs/msinfo32/resource.h b/programs/msinfo32/resource.h new file mode 100644 index 0000000..47c3652 --- /dev/null +++ b/programs/msinfo32/resource.h @@ -0,0 +1,19 @@ +/* + * Copyright 2016 Alex Henrie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define STRING_SYSTEM_INFO 100 -- 2.10.0 From ale.goujon at gmail.com Tue Oct 4 15:49:05 2016 From: ale.goujon at gmail.com (GOUJON Alexandre) Date: Tue, 4 Oct 2016 22:49:05 +0200 Subject: [PATCH] msvcrt: Implement __std_type_info_hash Message-ID: <1475614145-3130-1-git-send-email-ale.goujon@gmail.com> Fixes https://bugs.winehq.org/show_bug.cgi?id=41437 Signed-off-by: GOUJON Alexandre --- dlls/msvcrt/cpp.c | 21 ++++++++++++++++----- dlls/ucrtbase/tests/cpp.c | 4 +++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/dlls/msvcrt/cpp.c b/dlls/msvcrt/cpp.c index 0ffe61e..cc06c07 100644 --- a/dlls/msvcrt/cpp.c +++ b/dlls/msvcrt/cpp.c @@ -1591,20 +1591,31 @@ void CDECL MSVCRT_type_info_destroy_list(SLIST_HEADER *header) /****************************************************************** * __std_type_info_hash (UCRTBASE.@) - * - * TODO: 64-bit version of the function uses different constants */ MSVCRT_size_t CDECL MSVCRT_type_info_hash(const type_info140 *ti) { - MSVCRT_size_t hash = 0x811c9dc5; + MSVCRT_size_t hash; + MSVCRT_size_t fnvPrime; const char *p; + if(sizeof(void*) == sizeof(int)) + { + hash = 0x811c9dc5; + fnvPrime = 0x1000193; + } + else + { + hash = 0xcbf29ce484222325; + fnvPrime = 0x100000001b3; + } + TRACE("(%p)->%s\n", ti, ti->mangled); for(p = ti->mangled+1; *p; p++) { hash ^= *p; - hash *= 0x1000193; + hash *= fnvPrime; } - return hash; + + return hash ^ (hash >> 32); } #endif diff --git a/dlls/ucrtbase/tests/cpp.c b/dlls/ucrtbase/tests/cpp.c index 1a01fea..659269c 100644 --- a/dlls/ucrtbase/tests/cpp.c +++ b/dlls/ucrtbase/tests/cpp.c @@ -163,7 +163,7 @@ static void test___std_type_info(void) ti1.mangled[2] = 0; hash1 = p___std_type_info_hash(&ti1); #ifdef _WIN64 - todo_wine ok(hash1 == 0xcbf29ce44fd0bfc1, "hash = %p\n", (void*)hash1); + ok(hash1 == 0xcbf29ce44fd0bfc1, "hash = %p\n", (void*)hash1); #else ok(hash1 == 0x811c9dc5, "hash = %p\n", (void*)hash1); #endif @@ -176,6 +176,8 @@ static void test___std_type_info(void) hash1 = p___std_type_info_hash(&ti1); if(sizeof(void*) == sizeof(int)) ok(hash1 == 0x40c5b8c, "hash = %p\n", (void*)hash1); + else + ok(hash1 == 0xaf63bc4c29620a60, "hash = %p\n", (void*)hash1); ok(hash1 != hash2, "hash1 == hash2 for different strings\n"); ti1.mangled[1] = 2; -- 2.7.4 From aric at codeweavers.com Tue Oct 4 19:23:19 2016 From: aric at codeweavers.com (Aric Stewart) Date: Tue, 4 Oct 2016 19:23:19 -0500 Subject: [PATCH] winebus.sys: Implement common IRP_MJ_POWER handling Message-ID: Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_udev.c | 1 + dlls/winebus.sys/main.c | 9 +++++++++ 3 files changed, 11 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-winebus.sys-Implement-common-IRP_MJ_POWER-handling.txt Type: text/x-patch Size: 2085 bytes Desc: not available URL: From hugh.mcmaster at outlook.com Tue Oct 4 22:26:31 2016 From: hugh.mcmaster at outlook.com (Hugh McMaster) Date: Wed, 5 Oct 2016 03:26:31 +0000 Subject: [PATCH v3] msinfo32: Display an About dialog when the program is run Message-ID: From: Alex Henrie Signed-off-by: Alex Henrie Signed-off-by: Hugh McMaster Changes since v2: * Remove camelcase from the WCHAR buffer variable. * Split the resulting long line. --- programs/msinfo32/Makefile.in | 3 +++ programs/msinfo32/main.c | 9 +++++++++ programs/msinfo32/msinfo32.rc | 24 ++++++++++++++++++++++++ programs/msinfo32/resource.h | 19 +++++++++++++++++++ 4 files changed, 55 insertions(+) create mode 100644 programs/msinfo32/msinfo32.rc create mode 100644 programs/msinfo32/resource.h diff --git a/programs/msinfo32/Makefile.in b/programs/msinfo32/Makefile.in index e958c27..d752c91 100644 --- a/programs/msinfo32/Makefile.in +++ b/programs/msinfo32/Makefile.in @@ -1,5 +1,8 @@ MODULE = msinfo32.exe APPMODE = -mwindows -municode +IMPORTS = shell32 user32 C_SRCS = \ main.c + +RC_SRCS = msinfo32.rc diff --git a/programs/msinfo32/main.c b/programs/msinfo32/main.c index 77bb927..f64d266 100644 --- a/programs/msinfo32/main.c +++ b/programs/msinfo32/main.c @@ -16,18 +16,27 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include +#include + #include "wine/debug.h" +#include "resource.h" WINE_DEFAULT_DEBUG_CHANNEL(msinfo); int wmain(int argc, WCHAR *argv[]) { int i; + WCHAR system_info[64]; WINE_FIXME("stub:"); for (i = 0; i < argc; i++) WINE_FIXME(" %s", wine_dbgstr_w(argv[i])); WINE_FIXME("\n"); + LoadStringW(GetModuleHandleW(NULL), STRING_SYSTEM_INFO, + system_info, sizeof(system_info)/sizeof(WCHAR)); + ShellAboutW(NULL, system_info, NULL, NULL); + return 0; } diff --git a/programs/msinfo32/msinfo32.rc b/programs/msinfo32/msinfo32.rc new file mode 100644 index 0000000..ce4ab62 --- /dev/null +++ b/programs/msinfo32/msinfo32.rc @@ -0,0 +1,24 @@ +/* + * Copyright 2016 Alex Henrie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "resource.h" + +STRINGTABLE +{ + STRING_SYSTEM_INFO, "System Information" +} diff --git a/programs/msinfo32/resource.h b/programs/msinfo32/resource.h new file mode 100644 index 0000000..47c3652 --- /dev/null +++ b/programs/msinfo32/resource.h @@ -0,0 +1,19 @@ +/* + * Copyright 2016 Alex Henrie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define STRING_SYSTEM_INFO 100 -- 2.7.4 From austinenglish at gmail.com Wed Oct 5 01:05:57 2016 From: austinenglish at gmail.com (Austin English) Date: Wed, 5 Oct 2016 01:05:57 -0500 Subject: subst: add stub program Message-ID: https://bugs.winehq.org/show_bug.cgi?id=41427 -- -Austin GPG: 14FB D7EA A041 937B -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-subst-add-stub-program.patch Type: text/x-diff Size: 2493 bytes Desc: not available URL: From hans at codeweavers.com Wed Oct 5 02:46:26 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Wed, 5 Oct 2016 09:46:26 +0200 Subject: [1/3] wbemprox: Fix the variant type for Win32_SystemEnclosure.ChassisTypes. Message-ID: <1475653588-12364-1-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/wbemprox/builtin.c | 2 +- dlls/wbemprox/tests/query.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index 13f708f..4beac36 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -629,7 +629,7 @@ static const struct column col_stdregprov[] = static const struct column col_systemenclosure[] = { { prop_captionW, CIM_STRING }, - { prop_chassistypesW, CIM_UINT16|CIM_FLAG_ARRAY }, + { prop_chassistypesW, CIM_UINT16|CIM_FLAG_ARRAY, VT_I4|VT_ARRAY }, { prop_descriptionW, CIM_STRING }, { prop_lockpresentW, CIM_BOOLEAN }, { prop_manufacturerW, CIM_STRING }, diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c index c0889f9..aab819d 100644 --- a/dlls/wbemprox/tests/query.c +++ b/dlls/wbemprox/tests/query.c @@ -590,7 +590,6 @@ static void test_Win32_SystemEnclosure( IWbemServices *services ) VariantInit( &val ); hr = IWbemClassObject_Get( obj, chassistypesW, 0, &val, &type, NULL ); ok( hr == S_OK, "failed to get chassis types %08x\n", hr ); - todo_wine ok( V_VT( &val ) == (VT_I4|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &val ) ); ok( type == (CIM_UINT16|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type ); hr = SafeArrayAccessData( V_ARRAY( &val ), (void **)&data ); -- 2.1.4 From hans at codeweavers.com Wed Oct 5 02:46:27 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Wed, 5 Oct 2016 09:46:27 +0200 Subject: [2/3] wbemprox: Return NULL for Win32_BIOS.IdentificationCode. Message-ID: <1475653588-12364-2-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/wbemprox/builtin.c | 2 +- dlls/wbemprox/tests/query.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index 4beac36..436a351 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -1066,7 +1066,7 @@ static const struct record_baseboard data_baseboard[] = }; static const struct record_bios data_bios[] = { - { bios_descriptionW, bios_descriptionW, bios_manufacturerW, bios_nameW, bios_releasedateW, bios_serialnumberW, + { bios_descriptionW, NULL, bios_manufacturerW, bios_nameW, bios_releasedateW, bios_serialnumberW, bios_smbiosbiosversionW, bios_versionW } }; static const struct record_computersystemproduct data_compsysproduct[] = diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c index aab819d..c31fce0 100644 --- a/dlls/wbemprox/tests/query.c +++ b/dlls/wbemprox/tests/query.c @@ -310,7 +310,6 @@ static void test_Win32_Bios( IWbemServices *services ) VariantInit( &val ); hr = IWbemClassObject_Get( obj, identificationcodeW, 0, &val, &type, NULL ); ok( hr == S_OK, "failed to get identication code %08x\n", hr ); - todo_wine ok( V_VT( &val ) == VT_NULL, "unexpected variant type 0x%x\n", V_VT( &val ) ); ok( type == CIM_STRING, "unexpected type 0x%x\n", type ); VariantClear( &val ); -- 2.1.4 From hans at codeweavers.com Wed Oct 5 02:46:28 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Wed, 5 Oct 2016 09:46:28 +0200 Subject: [3/3] wbemprox: Get rid of hard-coded OS version numbers. Message-ID: <1475653588-12364-3-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/wbemprox/builtin.c | 122 ++++++++++++++++++++++++++++++++--------- dlls/wbemprox/tests/query.c | 128 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+), 26 deletions(-) diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index 436a351..b344a12 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -494,16 +494,16 @@ static const struct column col_networkadapterconfig[] = }; static const struct column col_os[] = { - { prop_buildnumberW, CIM_STRING }, - { prop_captionW, CIM_STRING }, + { prop_buildnumberW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC }, { prop_codesetW, CIM_STRING|COL_FLAG_DYNAMIC }, { prop_countrycodeW, CIM_STRING|COL_FLAG_DYNAMIC }, - { prop_csdversionW, CIM_STRING }, + { prop_csdversionW, CIM_STRING|COL_FLAG_DYNAMIC }, { prop_installdateW, CIM_DATETIME }, { prop_lastbootuptimeW, CIM_DATETIME|COL_FLAG_DYNAMIC }, { prop_localdatetimeW, CIM_DATETIME|COL_FLAG_DYNAMIC }, { prop_localeW, CIM_STRING|COL_FLAG_DYNAMIC }, - { prop_nameW, CIM_STRING }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, { prop_osarchitectureW, CIM_STRING }, { prop_oslanguageW, CIM_UINT32, VT_I4 }, { prop_osproductsuiteW, CIM_UINT32, VT_I4 }, @@ -515,7 +515,7 @@ static const struct column col_os[] = { prop_suitemaskW, CIM_UINT32, VT_I4 }, { prop_systemdirectoryW, CIM_STRING|COL_FLAG_DYNAMIC }, { prop_totalvisiblememorysizeW, CIM_UINT64 }, - { prop_versionW, CIM_STRING } + { prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC } }; static const struct column col_param[] = { @@ -729,24 +729,10 @@ static const WCHAR os_32bitW[] = {'3','2','-','b','i','t',0}; static const WCHAR os_64bitW[] = {'6','4','-','b','i','t',0}; -static const WCHAR os_buildnumberW[] = - {'2','6','0','0',0}; -static const WCHAR os_captionW[] = - {'M','i','c','r','o','s','o','f','t',' ','W','i','n','d','o','w','s',' ','X','P',' ', - 'V','e','r','s','i','o','n',' ','=',' ','5','.','1','.','2','6','0','0',0}; -static const WCHAR os_csdversionW[] = - {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','3',0}; static const WCHAR os_installdateW[] = {'2','0','1','4','0','1','0','1','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0}; -static const WCHAR os_nameW[] = - {'M','i','c','r','o','s','o','f','t',' ','W','i','n','d','o','w','s',' ','X','P',' ', - 'P','r','o','f','e','s','s','i','o','n','a','l','|','C',':','\\','W','I','N','D','O','W','S', - '|','\\','D','e','v','i','c','e','\\','H','a','r','d','d','i','s','k','0', - '\\','P','a','r','t','i','t','i','o','n','1',0}; static const WCHAR os_serialnumberW[] = {'1','2','3','4','5','-','O','E','M','-','1','2','3','4','5','6','7','-','1','2','3','4','5',0}; -static const WCHAR os_versionW[] = - {'5','.','1','.','2','6','0','0',0}; static const WCHAR physicalmedia_tagW[] = {'\\','\\','.','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0',0}; static const WCHAR sounddevice_productnameW[] = @@ -2624,38 +2610,122 @@ static WCHAR *get_locale(void) if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, ret, 5 ); return ret; } +static WCHAR *get_osbuildnumber( OSVERSIONINFOEXW *ver ) +{ + static const WCHAR fmtW[] = {'%','u',0}; + WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) ); + if (ret) sprintfW( ret, fmtW, ver->dwBuildNumber ); + return ret; +} +static WCHAR *get_oscaption( OSVERSIONINFOEXW *ver ) +{ + static const WCHAR windowsW[] = + {'M','i','c','r','o','s','o','f','t',' ','W','i','n','d','o','w','s',' '}; + static const WCHAR win2000W[] = + {'2','0','0','0',' ','P','r','o','f','e','s','s','i','o','n','a','l',0}; + static const WCHAR win2003W[] = + {'S','e','r','v','e','r',' ','2','0','0','3',' ','S','t','a','n','d','a','r','d',' ','E','d','i','t','i','o','n',0}; + static const WCHAR winxpW[] = + {'X','P',' ','P','r','o','f','e','s','s','i','o','n','a','l',0}; + static const WCHAR winxp64W[] = + {'X','P',' ','P','r','o','f','e','s','s','i','o','n','a','l',' ','x','6','4',' ','E','d','i','t','i','o','n',0}; + static const WCHAR vistaW[] = + {'V','i','s','t','a',' ','U','l','t','i','m','a','t','e',0}; + static const WCHAR win2008W[] = + {'S','e','r','v','e','r',' ','2','0','0','8',' ','S','t','a','n','d','a','r','d',0}; + static const WCHAR win7W[] = + {'7',' ','P','r','o','f','e','s','s','i','o','n','a','l',0}; + static const WCHAR win2008r2W[] = + {'S','e','r','v','e','r',' ','2','0','0','8',' ','R','2',' ','S','t','a','n','d','a','r','d',0}; + static const WCHAR win8W[] = + {'8',' ','P','r','o',0}; + static const WCHAR win81W[] = + {'8','.','1',' ','P','r','o',0}; + static const WCHAR win10W[] = + {'1','0',' ','P','r','o',0}; + int len = sizeof(windowsW)/sizeof(windowsW[0]); + WCHAR *ret; + + if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(win2003W) ))) return NULL; + memcpy( ret, windowsW, sizeof(windowsW) ); + if (ver->dwMajorVersion == 10 && ver->dwMinorVersion == 0) memcpy( ret + len, win10W, sizeof(win10W) ); + else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 3) memcpy( ret + len, win8W, sizeof(win8W) ); + else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 2) memcpy( ret + len, win81W, sizeof(win81W) ); + else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 1) + { + if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, win7W, sizeof(win7W) ); + else memcpy( ret + len, win2008r2W, sizeof(win2008r2W) ); + } + else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 0) + { + if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, vistaW, sizeof(vistaW) ); + else memcpy( ret + len, win2008W, sizeof(win2008W) ); + } + else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 2) + { + if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, winxp64W, sizeof(winxp64W) ); + else memcpy( ret + len, win2003W, sizeof(win2003W) ); + } + else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 1) memcpy( ret + len, winxpW, sizeof(winxpW) ); + else memcpy( ret + len, win2000W, sizeof(win2000W) ); + return ret; +} +static WCHAR *get_osname( const WCHAR *caption ) +{ + static const WCHAR partitionW[] = + {'|','C',':','\\','W','I','N','D','O','W','S','|','\\','D','e','v','i','c','e','\\', + 'H','a','r','d','d','i','s','k','0','\\','P','a','r','t','i','t','i','o','n','1',0}; + int len = strlenW( caption ); + WCHAR *ret; + + if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(partitionW) ))) return NULL; + memcpy( ret, caption, len * sizeof(WCHAR) ); + memcpy( ret + len, partitionW, sizeof(partitionW) ); + return ret; +} +static WCHAR *get_osversion( OSVERSIONINFOEXW *ver ) +{ + static const WCHAR fmtW[] = {'%','u','.','%','u','.','%','u',0}; + WCHAR *ret = heap_alloc( 33 * sizeof(WCHAR) ); + if (ret) sprintfW( ret, fmtW, ver->dwMajorVersion, ver->dwMinorVersion, ver->dwBuildNumber ); + return ret; +} static enum fill_status fill_os( struct table *table, const struct expr *cond ) { struct record_operatingsystem *rec; enum fill_status status = FILL_STATUS_UNFILTERED; + OSVERSIONINFOEXW ver; UINT row = 0; if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + ver.dwOSVersionInfoSize = sizeof(ver); + GetVersionExW( (OSVERSIONINFOW *)&ver ); + rec = (struct record_operatingsystem *)table->data; - rec->buildnumber = os_buildnumberW; - rec->caption = os_captionW; + rec->buildnumber = get_osbuildnumber( &ver ); + rec->caption = get_oscaption( &ver ); rec->codeset = get_codeset(); rec->countrycode = get_countrycode(); - rec->csdversion = os_csdversionW; + rec->csdversion = ver.szCSDVersion[0] ? heap_strdupW( ver.szCSDVersion ) : NULL; rec->installdate = os_installdateW; rec->lastbootuptime = get_lastbootuptime(); rec->localdatetime = get_localdatetime(); rec->locale = get_locale(); - rec->name = os_nameW; + rec->name = get_osname( rec->caption ); rec->osarchitecture = get_osarchitecture(); rec->oslanguage = GetSystemDefaultLangID(); rec->osproductsuite = 2461140; /* Windows XP Professional */ rec->ostype = 18; /* WINNT */ rec->primary = -1; rec->serialnumber = os_serialnumberW; - rec->servicepackmajor = 3; - rec->servicepackminor = 0; + rec->servicepackmajor = ver.wServicePackMajor; + rec->servicepackminor = ver.wServicePackMinor; rec->suitemask = 272; /* Single User + Terminal */ rec->systemdirectory = get_systemdirectory(); rec->totalvisiblememorysize = get_total_physical_memory() / 1024; - rec->version = os_versionW; + rec->version = get_osversion( &ver ); if (!match_row( table, row, cond, &status )) free_row_values( table, row ); else row++; diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c index c31fce0..d41aa11 100644 --- a/dlls/wbemprox/tests/query.c +++ b/dlls/wbemprox/tests/query.c @@ -1049,6 +1049,133 @@ static void test_SystemSecurity( IWbemServices *services ) SysFreeString( class ); } +static void test_OperatingSystem( IWbemServices *services ) +{ + static const WCHAR queryW[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_', + 'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0}; + static const WCHAR buildnumberW[] = {'B','u','i','l','d','N','u','m','b','e','r',0}; + static const WCHAR captionW[] = {'C','a','p','t','i','o','n',0}; + static const WCHAR csdversionW[] = {'C','S','D','V','e','r','s','i','o','n',0}; + static const WCHAR nameW[] = {'N','a','m','e',0}; + static const WCHAR osproductsuiteW[] = {'O','S','P','r','o','d','u','c','t','S','u','i','t','e',0}; + static const WCHAR ostypeW[] = {'O','S','T','y','p','e',0}; + static const WCHAR suitemaskW[] = {'S','u','i','t','e','M','a','s','k',0}; + static const WCHAR versionW[] = {'V','e','r','s','i','o','n',0}; + static const WCHAR servicepackmajorW[] = + {'S','e','r','v','i','c','e','P','a','c','k','M','a','j','o','r','V','e','r','s','i','o','n',0}; + static const WCHAR servicepackminorW[] = + {'S','e','r','v','i','c','e','P','a','c','k','M','i','n','o','r','V','e','r','s','i','o','n',0}; + BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW ); + IEnumWbemClassObject *result; + IWbemClassObject *obj; + CIMTYPE type; + ULONG count; + VARIANT val; + HRESULT hr; + + hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result ); + ok( hr == S_OK, "IWbemServices_ExecQuery failed %08x\n", hr ); + + hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count ); + ok( hr == S_OK, "IEnumWbemClassObject_Next failed %08x\n", hr ); + + type = 0xdeadbeef; + VariantInit( &val ); + hr = IWbemClassObject_Get( obj, buildnumberW, 0, &val, &type, NULL ); + ok( hr == S_OK, "failed to get buildnumber %08x\n", hr ); + ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) ); + ok( type == CIM_STRING, "unexpected type 0x%x\n", type ); + trace( "buildnumber: %s\n", wine_dbgstr_w(V_BSTR( &val )) ); + VariantClear( &val ); + + type = 0xdeadbeef; + VariantInit( &val ); + hr = IWbemClassObject_Get( obj, captionW, 0, &val, &type, NULL ); + ok( hr == S_OK, "failed to get caption %08x\n", hr ); + ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) ); + ok( type == CIM_STRING, "unexpected type 0x%x\n", type ); + trace( "caption: %s\n", wine_dbgstr_w(V_BSTR( &val )) ); + VariantClear( &val ); + + type = 0xdeadbeef; + VariantInit( &val ); + hr = IWbemClassObject_Get( obj, csdversionW, 0, &val, &type, NULL ); + ok( hr == S_OK, "failed to get csdversion %08x\n", hr ); + ok( V_VT( &val ) == VT_BSTR || V_VT( &val ) == VT_NULL, "unexpected variant type 0x%x\n", V_VT( &val ) ); + ok( type == CIM_STRING, "unexpected type 0x%x\n", type ); + trace( "csdversion: %s\n", wine_dbgstr_w(V_BSTR( &val )) ); + VariantClear( &val ); + + type = 0xdeadbeef; + VariantInit( &val ); + hr = IWbemClassObject_Get( obj, nameW, 0, &val, &type, NULL ); + ok( hr == S_OK, "failed to get name %08x\n", hr ); + ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) ); + ok( type == CIM_STRING, "unexpected type 0x%x\n", type ); + trace( "name: %s\n", wine_dbgstr_w(V_BSTR( &val )) ); + VariantClear( &val ); + + type = 0xdeadbeef; + VariantInit( &val ); + hr = IWbemClassObject_Get( obj, osproductsuiteW, 0, &val, &type, NULL ); + ok( hr == S_OK, "failed to get osproductsuite %08x\n", hr ); + ok( V_VT( &val ) == VT_I4 || broken(V_VT( &val ) == VT_NULL) /* winxp */, "unexpected variant type 0x%x\n", V_VT( &val ) ); + ok( type == CIM_UINT32, "unexpected type 0x%x\n", type ); + trace( "osproductsuite: %d (%08x)\n", V_I4( &val ), V_I4( &val ) ); + VariantClear( &val ); + + type = 0xdeadbeef; + VariantInit( &val ); + hr = IWbemClassObject_Get( obj, ostypeW, 0, &val, &type, NULL ); + ok( hr == S_OK, "failed to get ostype %08x\n", hr ); + ok( V_VT( &val ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &val ) ); + ok( type == CIM_UINT16, "unexpected type 0x%x\n", type ); + trace( "ostype: %d\n", V_I4( &val ) ); + VariantClear( &val ); + + type = 0xdeadbeef; + VariantInit( &val ); + hr = IWbemClassObject_Get( obj, servicepackmajorW, 0, &val, &type, NULL ); + ok( hr == S_OK, "failed to get servicepackmajor %08x\n", hr ); + ok( V_VT( &val ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &val ) ); + ok( type == CIM_UINT16, "unexpected type 0x%x\n", type ); + trace( "servicepackmajor: %d\n", V_I4( &val ) ); + VariantClear( &val ); + + type = 0xdeadbeef; + VariantInit( &val ); + hr = IWbemClassObject_Get( obj, servicepackminorW, 0, &val, &type, NULL ); + ok( hr == S_OK, "failed to get servicepackminor %08x\n", hr ); + ok( V_VT( &val ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &val ) ); + ok( type == CIM_UINT16, "unexpected type 0x%x\n", type ); + trace( "servicepackminor: %d\n", V_I4( &val ) ); + VariantClear( &val ); + + type = 0xdeadbeef; + VariantInit( &val ); + hr = IWbemClassObject_Get( obj, suitemaskW, 0, &val, &type, NULL ); + ok( hr == S_OK, "failed to get suitemask %08x\n", hr ); + ok( V_VT( &val ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &val ) ); + ok( type == CIM_UINT32, "unexpected type 0x%x\n", type ); + trace( "suitemask: %d (%08x)\n", V_I4( &val ), V_I4( &val ) ); + VariantClear( &val ); + + type = 0xdeadbeef; + VariantInit( &val ); + hr = IWbemClassObject_Get( obj, versionW, 0, &val, &type, NULL ); + ok( hr == S_OK, "failed to get version %08x\n", hr ); + ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) ); + ok( type == CIM_STRING, "unexpected type 0x%x\n", type ); + trace( "version: %s\n", wine_dbgstr_w(V_BSTR( &val )) ); + VariantClear( &val ); + + IWbemClassObject_Release( obj ); + IEnumWbemClassObject_Release( result ); + SysFreeString( query ); + SysFreeString( wql ); +} + START_TEST(query) { static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0}; @@ -1086,6 +1213,7 @@ START_TEST(query) test_query_async( services ); test_GetNames( services ); test_SystemSecurity( services ); + test_OperatingSystem( services ); SysFreeString( path ); IWbemServices_Release( services ); -- 2.1.4 From mstefani at redhat.de Wed Oct 5 03:27:56 2016 From: mstefani at redhat.de (Michael Stefaniuc) Date: Wed, 5 Oct 2016 10:27:56 +0200 Subject: [PATCH 1/4] dmusic/tests: Add basic COM tests for IDirectMusicPort. Message-ID: <20161005082756.GA3569@redhat.com> Signed-off-by: Michael Stefaniuc --- dlls/dmusic/tests/dmusic.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/dlls/dmusic/tests/dmusic.c b/dlls/dmusic/tests/dmusic.c index 5a0c095..69df51d 100644 --- a/dlls/dmusic/tests/dmusic.c +++ b/dlls/dmusic/tests/dmusic.c @@ -379,6 +379,65 @@ static BOOL missing_dmusic(void) return TRUE; } +static void test_COM_synthport(void) +{ + IDirectMusic *dmusic = NULL; + IDirectMusicPort *port = NULL; + IDirectMusicPortDownload *dmpd; + IDirectMusicThru *dmt; + IKsControl *iksc; + IReferenceClock *clock; + IUnknown *unk; + DMUS_PORTPARAMS port_params; + ULONG refcount; + HRESULT hr; + + /* Create a IDirectMusicPort */ + hr = CoCreateInstance(&CLSID_DirectMusic, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusic, + (void**)&dmusic); + ok(hr == S_OK, "Cannot create DirectMusic object (%x)\n", hr); + port_params.dwSize = sizeof(port_params); + port_params.dwValidParams = DMUS_PORTPARAMS_CHANNELGROUPS | DMUS_PORTPARAMS_AUDIOCHANNELS; + port_params.dwChannelGroups = 1; + port_params.dwAudioChannels = 2; + hr = IDirectMusic_SetDirectSound(dmusic, NULL, NULL); + ok(hr == S_OK, "IDirectMusic_SetDirectSound returned: %x\n", hr); + hr = IDirectMusic_CreatePort(dmusic, &GUID_NULL, &port_params, &port, NULL); + ok(hr == S_OK, "IDirectMusic_CreatePort returned: %x\n", hr); + + /* Same refcount for all DirectMusicPort interfaces */ + refcount = IDirectMusicPort_AddRef(port); + ok(refcount == 2, "refcount == %u, expected 2\n", refcount); + + hr = IDirectMusicPort_QueryInterface(port, &IID_IDirectMusicPortDownload, (void**)&dmpd); + ok(hr == S_OK, "QueryInterface for IID_IDirectMusicPortDownload failed: %08x\n", hr); + refcount = IDirectMusicPortDownload_AddRef(dmpd); + ok(refcount == 4, "refcount == %u, expected 4\n", refcount); + IDirectMusicPortDownload_Release(dmpd); + + hr = IDirectMusicPort_QueryInterface(port, &IID_IKsControl, (void**)&iksc); + todo_wine ok(hr == S_OK, "QueryInterface for IID_IKsControl failed: %08x\n", hr); + if (hr == S_OK) { + refcount = IKsControl_AddRef(iksc); + ok(refcount == 5, "refcount == %u, expected 5\n", refcount); + IKsControl_Release(iksc); + } + + hr = IDirectMusicPort_QueryInterface(port, &IID_IUnknown, (void**)&unk); + ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr); + refcount = IUnknown_AddRef(unk); + todo_wine ok(refcount == 6, "refcount == %u, expected 6\n", refcount); + IUnknown_Release(unk); + + /* Unsupported interface */ + hr = IDirectMusicPort_QueryInterface(port, &IID_IDirectMusicThru, (void**)&dmt); + todo_wine ok(hr == E_NOINTERFACE, "QueryInterface for IID_IDirectMusicThru failed: %08x\n", hr); + hr = IDirectMusicPort_QueryInterface(port, &IID_IReferenceClock, (void**)&clock); + ok(hr == E_NOINTERFACE, "QueryInterface for IID_IReferenceClock failed: %08x\n", hr); + + while (IDirectMusicPort_Release(port)); +} + START_TEST(dmusic) { CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -391,6 +450,7 @@ START_TEST(dmusic) } test_COM(); test_COM_dmcoll(); + test_COM_synthport(); test_dmusic(); test_dmbuffer(); test_dmcoll(); -- 2.5.5 From mstefani at redhat.de Wed Oct 5 03:28:22 2016 From: mstefani at redhat.de (Michael Stefaniuc) Date: Wed, 5 Oct 2016 10:28:22 +0200 Subject: [PATCH 2/4] dmusic: Simplify the IDirectMusicPort_QueryInterface implementation. Message-ID: <20161005082822.GB3569@redhat.com> Signed-off-by: Michael Stefaniuc --- dlls/dmusic/port.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/dlls/dmusic/port.c b/dlls/dmusic/port.c index d919c10..95db9e0 100644 --- a/dlls/dmusic/port.c +++ b/dlls/dmusic/port.c @@ -130,23 +130,21 @@ static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_QueryInterface(LPDIRECTMUSI TRACE("(%p/%p)->(%s, %p)\n", iface, This, debugstr_dmguid(riid), ret_iface); - if (IsEqualIID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirectMusicPort)) { + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirectMusicPort)) *ret_iface = &This->IDirectMusicPort_iface; - IDirectMusicPort_AddRef((LPDIRECTMUSICPORT)*ret_iface); - return S_OK; - } else if (IsEqualGUID(riid, &IID_IDirectMusicPortDownload)) { + else if (IsEqualGUID(riid, &IID_IDirectMusicPortDownload)) *ret_iface = &This->IDirectMusicPortDownload_iface; - IDirectMusicPortDownload_AddRef((LPDIRECTMUSICPORTDOWNLOAD)*ret_iface); - return S_OK; - } else if (IsEqualGUID(riid, &IID_IDirectMusicThru)) { + else if (IsEqualGUID(riid, &IID_IDirectMusicThru)) *ret_iface = &This->IDirectMusicThru_iface; - IDirectMusicThru_AddRef((LPDIRECTMUSICTHRU)*ret_iface); - return S_OK; + else { + WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ret_iface); + *ret_iface = NULL; + return E_NOINTERFACE; } - WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ret_iface); + IUnknown_AddRef((IUnknown*)*ret_iface); - return E_NOINTERFACE; + return S_OK; } static ULONG WINAPI SynthPortImpl_IDirectMusicPort_AddRef(LPDIRECTMUSICPORT iface) -- 2.5.5 From mstefani at redhat.de Wed Oct 5 03:28:54 2016 From: mstefani at redhat.de (Michael Stefaniuc) Date: Wed, 5 Oct 2016 10:28:54 +0200 Subject: [PATCH 3/4] dmusic: Move the SynthPortImpl struct to where it is used. Message-ID: <20161005082854.GC3569@redhat.com> Signed-off-by: Michael Stefaniuc --- dlls/dmusic/dmusic_private.h | 24 ------------------------ dlls/dmusic/port.c | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/dlls/dmusic/dmusic_private.h b/dlls/dmusic/dmusic_private.h index 44d5d57..07f5f1d 100644 --- a/dlls/dmusic/dmusic_private.h +++ b/dlls/dmusic/dmusic_private.h @@ -53,8 +53,6 @@ typedef struct IReferenceClockImpl IReferenceClockImpl; typedef struct IDirectMusicInstrumentImpl IDirectMusicInstrumentImpl; -typedef struct SynthPortImpl SynthPortImpl; - /***************************************************************************** * Some stuff to make my life easier :=) */ @@ -159,28 +157,6 @@ struct IDirectMusicDownloadImpl { /* IDirectMusicDownloadImpl fields */ }; -/***************************************************************************** - * SynthPortImpl implementation structure - */ -struct SynthPortImpl { - /* IUnknown fields */ - IDirectMusicPort IDirectMusicPort_iface; - IDirectMusicPortDownload IDirectMusicPortDownload_iface; - IDirectMusicThru IDirectMusicThru_iface; - LONG ref; - - /* IDirectMusicPort fields */ - IDirectSound* pDirectSound; - IReferenceClock* pLatencyClock; - IDirectMusicSynth* synth; - IDirectMusicSynthSink* synth_sink; - BOOL fActive; - DMUS_PORTCAPS caps; - DMUS_PORTPARAMS params; - int nrofgroups; - DMUSIC_PRIVATE_CHANNEL_GROUP group[1]; -}; - /** Internal factory */ extern HRESULT DMUSIC_CreateSynthPortImpl(LPCGUID guid, LPVOID *object, LPUNKNOWN unkouter, LPDMUS_PORTPARAMS port_params, LPDMUS_PORTCAPS port_caps, DWORD device) DECLSPEC_HIDDEN; extern HRESULT DMUSIC_CreateMidiOutPortImpl(LPCGUID guid, LPVOID *object, LPUNKNOWN unkouter, LPDMUS_PORTPARAMS port_params, LPDMUS_PORTCAPS port_caps, DWORD device) DECLSPEC_HIDDEN; diff --git a/dlls/dmusic/port.c b/dlls/dmusic/port.c index 95db9e0..b694ef7 100644 --- a/dlls/dmusic/port.c +++ b/dlls/dmusic/port.c @@ -24,6 +24,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(dmusic); +typedef struct SynthPortImpl { + IDirectMusicPort IDirectMusicPort_iface; + IDirectMusicPortDownload IDirectMusicPortDownload_iface; + IDirectMusicThru IDirectMusicThru_iface; + LONG ref; + IDirectSound *pDirectSound; + IReferenceClock *pLatencyClock; + IDirectMusicSynth *synth; + IDirectMusicSynthSink *synth_sink; + BOOL fActive; + DMUS_PORTCAPS caps; + DMUS_PORTPARAMS params; + int nrofgroups; + DMUSIC_PRIVATE_CHANNEL_GROUP group[1]; +} SynthPortImpl; + static inline IDirectMusicDownloadedInstrumentImpl* impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument *iface) { return CONTAINING_RECORD(iface, IDirectMusicDownloadedInstrumentImpl, IDirectMusicDownloadedInstrument_iface); -- 2.5.5 From mstefani at redhat.de Wed Oct 5 03:36:59 2016 From: mstefani at redhat.de (Michael Stefaniuc) Date: Wed, 5 Oct 2016 10:36:59 +0200 Subject: [PATCH 4/4] dmusic: Support the IKsControl interface for the synth port. Message-ID: <20161005083659.GD3569@redhat.com> Based on a patch by Michael Müller. Signed-off-by: Michael Stefaniuc --- dlls/dmusic/dmusic_private.h | 1 + dlls/dmusic/port.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ dlls/dmusic/tests/dmusic.c | 12 +++---- 3 files changed, 84 insertions(+), 7 deletions(-) diff --git a/dlls/dmusic/dmusic_private.h b/dlls/dmusic/dmusic_private.h index 07f5f1d..cfe03fc 100644 --- a/dlls/dmusic/dmusic_private.h +++ b/dlls/dmusic/dmusic_private.h @@ -41,6 +41,7 @@ #include "dmusici.h" #include "dmusicf.h" #include "dmusics.h" +#include "dmksctrl.h" /***************************************************************************** * Interfaces diff --git a/dlls/dmusic/port.c b/dlls/dmusic/port.c index b694ef7..20477c1 100644 --- a/dlls/dmusic/port.c +++ b/dlls/dmusic/port.c @@ -28,6 +28,7 @@ typedef struct SynthPortImpl { IDirectMusicPort IDirectMusicPort_iface; IDirectMusicPortDownload IDirectMusicPortDownload_iface; IDirectMusicThru IDirectMusicThru_iface; + IKsControl IKsControl_iface; LONG ref; IDirectSound *pDirectSound; IReferenceClock *pLatencyClock; @@ -60,6 +61,11 @@ static inline SynthPortImpl *impl_from_SynthPortImpl_IDirectMusicThru(IDirectMus return CONTAINING_RECORD(iface, SynthPortImpl, IDirectMusicThru_iface); } +static inline SynthPortImpl *impl_from_IKsControl(IKsControl *iface) +{ + return CONTAINING_RECORD(iface, SynthPortImpl, IKsControl_iface); +} + /* IDirectMusicDownloadedInstrument IUnknown part follows: */ static HRESULT WINAPI IDirectMusicDownloadedInstrumentImpl_QueryInterface(IDirectMusicDownloadedInstrument *iface, REFIID riid, VOID **ret_iface) { @@ -152,6 +158,8 @@ static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_QueryInterface(LPDIRECTMUSI *ret_iface = &This->IDirectMusicPortDownload_iface; else if (IsEqualGUID(riid, &IID_IDirectMusicThru)) *ret_iface = &This->IDirectMusicThru_iface; + else if (IsEqualGUID(riid, &IID_IKsControl)) + *ret_iface = &This->IKsControl_iface; else { WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ret_iface); *ret_iface = NULL; @@ -686,6 +694,75 @@ static const IDirectMusicThruVtbl SynthPortImpl_DirectMusicThru_Vtbl = { SynthPortImpl_IDirectMusicThru_ThruChannel }; +static HRESULT WINAPI IKsControlImpl_QueryInterface(IKsControl *iface, REFIID riid, + void **ret_iface) +{ + SynthPortImpl *This = impl_from_IKsControl(iface); + + return IDirectMusicPort_QueryInterface(&This->IDirectMusicPort_iface, riid, ret_iface); +} + +static ULONG WINAPI IKsControlImpl_AddRef(IKsControl *iface) +{ + SynthPortImpl *This = impl_from_IKsControl(iface); + + return IDirectMusicPort_AddRef(&This->IDirectMusicPort_iface); +} + +static ULONG WINAPI IKsControlImpl_Release(IKsControl *iface) +{ + SynthPortImpl *This = impl_from_IKsControl(iface); + + return IDirectMusicPort_Release(&This->IDirectMusicPort_iface); +} + +static HRESULT WINAPI IKsControlImpl_KsProperty(IKsControl *iface, KSPROPERTY *prop, + ULONG prop_len, void *data, ULONG data_len, ULONG *ret_len) +{ + TRACE("(%p)->(%p, %u, %p, %u, %p)\n", iface, prop, prop_len, data, data_len, ret_len); + TRACE("prop = %s - %u - %u\n", debugstr_guid(&prop->Set), prop->Id, prop->Flags); + + if (prop->Flags != KSPROPERTY_TYPE_GET) + { + FIXME("prop flags %u not yet supported\n", prop->Flags); + return S_FALSE; + } + + if (data_len < sizeof(DWORD)) + return E_NOT_SUFFICIENT_BUFFER; + + FIXME("Unknown property %s\n", debugstr_guid(&prop->Set)); + *(DWORD*)data = FALSE; + *ret_len = sizeof(DWORD); + + return S_OK; +} + +static HRESULT WINAPI IKsControlImpl_KsMethod(IKsControl *iface, KSMETHOD *method, + ULONG method_len, void *data, ULONG data_len, ULONG *ret_len) +{ + FIXME("(%p)->(%p, %u, %p, %u, %p): stub\n", iface, method, method_len, data, data_len, ret_len); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IKsControlImpl_KsEvent(IKsControl *iface, KSEVENT *event, ULONG event_len, + void *data, ULONG data_len, ULONG *ret_len) +{ + FIXME("(%p)->(%p, %u, %p, %u, %p): stub\n", iface, event, event_len, data, data_len, ret_len); + + return E_NOTIMPL; +} + +static const IKsControlVtbl ikscontrol_vtbl = { + IKsControlImpl_QueryInterface, + IKsControlImpl_AddRef, + IKsControlImpl_Release, + IKsControlImpl_KsProperty, + IKsControlImpl_KsMethod, + IKsControlImpl_KsEvent +}; + HRESULT DMUSIC_CreateSynthPortImpl(LPCGUID guid, LPVOID *object, LPUNKNOWN unkouter, LPDMUS_PORTPARAMS port_params, LPDMUS_PORTCAPS port_caps, DWORD device) { SynthPortImpl *obj; @@ -704,6 +781,7 @@ HRESULT DMUSIC_CreateSynthPortImpl(LPCGUID guid, LPVOID *object, LPUNKNOWN unkou obj->IDirectMusicPort_iface.lpVtbl = &SynthPortImpl_DirectMusicPort_Vtbl; obj->IDirectMusicPortDownload_iface.lpVtbl = &SynthPortImpl_DirectMusicPortDownload_Vtbl; obj->IDirectMusicThru_iface.lpVtbl = &SynthPortImpl_DirectMusicThru_Vtbl; + obj->IKsControl_iface.lpVtbl = &ikscontrol_vtbl; obj->ref = 0; /* Will be inited by QueryInterface */ obj->fActive = FALSE; obj->params = *port_params; diff --git a/dlls/dmusic/tests/dmusic.c b/dlls/dmusic/tests/dmusic.c index 69df51d..b56bba4 100644 --- a/dlls/dmusic/tests/dmusic.c +++ b/dlls/dmusic/tests/dmusic.c @@ -416,17 +416,15 @@ static void test_COM_synthport(void) IDirectMusicPortDownload_Release(dmpd); hr = IDirectMusicPort_QueryInterface(port, &IID_IKsControl, (void**)&iksc); - todo_wine ok(hr == S_OK, "QueryInterface for IID_IKsControl failed: %08x\n", hr); - if (hr == S_OK) { - refcount = IKsControl_AddRef(iksc); - ok(refcount == 5, "refcount == %u, expected 5\n", refcount); - IKsControl_Release(iksc); - } + ok(hr == S_OK, "QueryInterface for IID_IKsControl failed: %08x\n", hr); + refcount = IKsControl_AddRef(iksc); + ok(refcount == 5, "refcount == %u, expected 5\n", refcount); + IKsControl_Release(iksc); hr = IDirectMusicPort_QueryInterface(port, &IID_IUnknown, (void**)&unk); ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr); refcount = IUnknown_AddRef(unk); - todo_wine ok(refcount == 6, "refcount == %u, expected 6\n", refcount); + ok(refcount == 6, "refcount == %u, expected 6\n", refcount); IUnknown_Release(unk); /* Unsupported interface */ -- 2.5.5 From mstefani at redhat.de Wed Oct 5 03:37:59 2016 From: mstefani at redhat.de (Michael Stefaniuc) Date: Wed, 5 Oct 2016 10:37:59 +0200 Subject: ws2_32: Use debugstr_guid() to trace GUIDs. Message-ID: <20161005083759.GE3569@redhat.com> Signed-off-by: Michael Stefaniuc --- dlls/ws2_32/socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 9d0b60e..e3c7507 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -7880,7 +7880,7 @@ int WINAPI WSAInstallServiceClassW(LPWSASERVICECLASSINFOW info) */ int WINAPI WSARemoveServiceClass(LPGUID info) { - FIXME("Request to remove service %p\n",info); + FIXME("Request to remove service %s\n", debugstr_guid(info)); SetLastError(WSATYPE_NOT_FOUND); return SOCKET_ERROR; } @@ -8569,7 +8569,7 @@ INT WINAPI WSCInstallNameSpace( LPWSTR identifier, LPWSTR path, DWORD namespace, */ INT WINAPI WSCUnInstallNameSpace( LPGUID lpProviderId ) { - FIXME("(%p) Stub!\n", lpProviderId); + FIXME("(%s) Stub!\n", debugstr_guid(lpProviderId)); return NO_ERROR; } -- 2.7.4 From huw at codeweavers.com Wed Oct 5 04:08:24 2016 From: huw at codeweavers.com (Huw Davies) Date: Wed, 5 Oct 2016 10:08:24 +0100 Subject: [PATCH 1/5] riched20: Use the provided style for the end-of-paragraph run. Message-ID: <1475658508-17196-1-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/caret.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index a47930f..26af743 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -549,7 +549,6 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, pos++; } else { /* handle EOLs */ ME_DisplayItem *tp, *end_run, *run, *prev; - ME_Style *tmp_style; int eol_len = 0; /* Find number of CR and LF in end of paragraph run */ @@ -594,13 +593,9 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, run = p->pRun; } - tmp_style = ME_GetInsertStyle(editor, nCursor); - /* ME_SplitParagraph increases style refcount */ - tp = ME_SplitParagraph(editor, run, run->member.run.style, eol_str, eol_len, 0); + tp = ME_SplitParagraph(editor, run, style, eol_str, eol_len, 0); end_run = ME_FindItemBack(tp, diRun); - ME_ReleaseStyle(end_run->member.run.style); - end_run->member.run.style = tmp_style; /* Move any cursors that were at the end of the previous run to the beginning of the new para */ prev = ME_FindItemBack( end_run, diRun ); -- 2.8.2 From huw at codeweavers.com Wed Oct 5 04:08:25 2016 From: huw at codeweavers.com (Huw Davies) Date: Wed, 5 Oct 2016 10:08:25 +0100 Subject: [PATCH 2/5] riched20: Alter ME_SaveTempStyle() to accept the new style. Message-ID: <1475658508-17196-2-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/editor.c | 6 +++--- dlls/riched20/editor.h | 2 +- dlls/riched20/style.c | 9 +++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 4adc74f..7b934fe 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -2392,7 +2392,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) } style = ME_GetInsertStyle(editor, 0); - ME_SaveTempStyle(editor); + ME_SaveTempStyle(editor, style); ME_ContinueCoalescingTransaction(editor); if (shift_is_down) ME_InsertEndRowFromCursor(editor, 0); @@ -2566,7 +2566,7 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode, if(editor->nTextLimit > ME_GetTextLength(editor) - (to-from)) { ME_Style *style = ME_GetInsertStyle(editor, 0); - ME_SaveTempStyle(editor); + ME_SaveTempStyle(editor, style); ME_ContinueCoalescingTransaction(editor); ME_InsertTextFromCursor(editor, 0, &wstr, 1, style); ME_ReleaseStyle(style); @@ -4538,7 +4538,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, ME_Style *style = ME_GetInsertStyle(editor, 0); hIMC = ITextHost_TxImmGetContext(editor->texthost); ME_DeleteSelection(editor); - ME_SaveTempStyle(editor); + ME_SaveTempStyle(editor, style); if (lParam & (GCS_RESULTSTR|GCS_COMPSTR)) { LPWSTR lpCompStr = NULL; diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index c62b3a4..b0a8a1a 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -76,7 +76,7 @@ ME_Style *ME_ApplyStyle(ME_TextEditor *ed, ME_Style *sSrc, CHARFORMAT2W *style) HFONT ME_SelectStyleFont(ME_Context *c, ME_Style *s) DECLSPEC_HIDDEN; void ME_UnselectStyleFont(ME_Context *c, ME_Style *s, HFONT hOldFont) DECLSPEC_HIDDEN; void ME_InitCharFormat2W(CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN; -void ME_SaveTempStyle(ME_TextEditor *editor) DECLSPEC_HIDDEN; +void ME_SaveTempStyle(ME_TextEditor *editor, ME_Style *style) DECLSPEC_HIDDEN; void ME_ClearTempStyle(ME_TextEditor *editor) DECLSPEC_HIDDEN; void ME_DumpStyleToBuf(CHARFORMAT2W *pFmt, char buf[2048]) DECLSPEC_HIDDEN; void ME_DumpStyle(ME_Style *s) DECLSPEC_HIDDEN; diff --git a/dlls/riched20/style.c b/dlls/riched20/style.c index 06c0e6f..0d2c16a 100644 --- a/dlls/riched20/style.c +++ b/dlls/riched20/style.c @@ -513,12 +513,13 @@ ME_Style *ME_GetInsertStyle(ME_TextEditor *editor, int nCursor) } } -void ME_SaveTempStyle(ME_TextEditor *editor) +void ME_SaveTempStyle(ME_TextEditor *editor, ME_Style *style) { ME_Style *old_style = editor->pBuffer->pCharStyle; - editor->pBuffer->pCharStyle = ME_GetInsertStyle(editor, 0); - if (old_style) - ME_ReleaseStyle(old_style); + + if (style) ME_AddRefStyle( style ); + editor->pBuffer->pCharStyle = style; + if (old_style) ME_ReleaseStyle( old_style ); } void ME_ClearTempStyle(ME_TextEditor *editor) -- 2.8.2 From huw at codeweavers.com Wed Oct 5 04:08:26 2016 From: huw at codeweavers.com (Huw Davies) Date: Wed, 5 Oct 2016 10:08:26 +0100 Subject: [PATCH 3/5] riched20: Set a temporary insert style for the new paragraph. Message-ID: <1475658508-17196-3-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/editor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 7b934fe..78cb50c 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -2392,7 +2392,6 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) } style = ME_GetInsertStyle(editor, 0); - ME_SaveTempStyle(editor, style); ME_ContinueCoalescingTransaction(editor); if (shift_is_down) ME_InsertEndRowFromCursor(editor, 0); @@ -2401,12 +2400,13 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) ME_InsertTextFromCursor(editor, 0, &endl, 1, style); else ME_InsertTextFromCursor(editor, 0, endlv10, 2, style); - ME_ReleaseStyle(style); ME_CommitCoalescingUndo(editor); SetCursor(NULL); ME_UpdateSelectionLinkAttribute(editor); ME_UpdateRepaint(editor, FALSE); + ME_SaveTempStyle(editor, style); /* set the temp insert style for the new para */ + ME_ReleaseStyle(style); } return TRUE; } -- 2.8.2 From huw at codeweavers.com Wed Oct 5 04:08:27 2016 From: huw at codeweavers.com (Huw Davies) Date: Wed, 5 Oct 2016 10:08:27 +0100 Subject: [PATCH 4/5] riched20: Set the format of the final eop to be that of the last char. Message-ID: <1475658508-17196-4-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/editor.c | 12 +++++++++++- dlls/riched20/tests/editor.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 78cb50c..d7abaa2 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -1648,7 +1648,17 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre if (newto > to + (editor->bEmulateVersion10 ? 1 : 0)) { WCHAR lastchar[3] = {'\0', '\0'}; int linebreakSize = editor->bEmulateVersion10 ? 2 : 1; - ME_Cursor linebreakCursor = *selEnd; + ME_Cursor linebreakCursor = *selEnd, lastcharCursor = *selEnd; + CHARFORMAT2W cf; + + /* Set the final eop to the char fmt of the last char */ + cf.cbSize = sizeof(cf); + cf.dwMask = CFM_ALL2; + ME_MoveCursorChars(editor, &lastcharCursor, -1, FALSE); + ME_GetCharFormat(editor, &lastcharCursor, &linebreakCursor, &cf); + ME_SetSelection(editor, newto, -1); + ME_SetSelectionCharFormat(editor, &cf); + ME_SetSelection(editor, newto, newto); ME_MoveCursorChars(editor, &linebreakCursor, -linebreakSize, FALSE); ME_GetTextW(editor, lastchar, 2, &linebreakCursor, linebreakSize, FALSE, FALSE); diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 218e20e..486291f 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -8372,6 +8372,43 @@ static void test_background(void) DestroyWindow(hwndRichEdit); } +static void test_eop_char_fmt(void) +{ + HWND edit = new_richedit( NULL ); + const char *rtf = "{\\rtf1{\\fonttbl{\\f0\\fswiss\\fprq2\\fcharset0 Arial;}{\\f1\\fnil\\fcharset2 Symbol;}}" + "{\\fs10{\\pard\\fs16\\fi200\\li360\\f0 First\\par" + "\\f0\\fs25 Second\\par" + "{\\f0\\fs26 Third}\\par" + "{\\f0\\fs22 Fourth}\\par}}}"; + EDITSTREAM es; + LRESULT result; + CHARFORMAT2W cf; + int i, num, expect_height; + + es.dwCookie = (DWORD_PTR)&rtf; + es.dwError = 0; + es.pfnCallback = test_EM_STREAMIN_esCallback; + num = SendMessageA( edit, EM_STREAMIN, SF_RTF, (LPARAM)&es ); + ok( num == 25, "got %d\n", num ); + + for (i = 0; i <= num; i++) + { + SendMessageW( edit, EM_SETSEL, i, i + 1 ); + cf.cbSize = sizeof(cf); + cf.dwMask = CFM_SIZE; + result = SendMessageW( edit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf ); + ok( cf.dwMask & CFM_SIZE, "%d: got %08x\n", i, cf.dwMask ); + if (i < 6) expect_height = 160; + else if (i < 13) expect_height = 250; + else if (i < 18) expect_height = 260; + else if (i == 18 || i == 25) expect_height = 250; + else expect_height = 220; + ok( cf.yHeight == expect_height, "%d: got %d\n", i, cf.yHeight ); + } + + DestroyWindow( edit ); +} + START_TEST( editor ) { BOOL ret; @@ -8443,6 +8480,7 @@ START_TEST( editor ) test_alignment_style(); test_rtf_specials(); test_background(); + test_eop_char_fmt(); /* Set the environment variable WINETEST_RICHED20 to keep windows * responsive and open for 30 seconds. This is useful for debugging. -- 2.8.2 From huw at codeweavers.com Wed Oct 5 04:08:28 2016 From: huw at codeweavers.com (Huw Davies) Date: Wed, 5 Oct 2016 10:08:28 +0100 Subject: [PATCH 5/5] riched20: Remove an unnecessary call to ME_SaveTempStyle(). Message-ID: <1475658508-17196-5-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/editor.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index d7abaa2..e2a44d3 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -2576,7 +2576,6 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode, if(editor->nTextLimit > ME_GetTextLength(editor) - (to-from)) { ME_Style *style = ME_GetInsertStyle(editor, 0); - ME_SaveTempStyle(editor, style); ME_ContinueCoalescingTransaction(editor); ME_InsertTextFromCursor(editor, 0, &wstr, 1, style); ME_ReleaseStyle(style); -- 2.8.2 From jkucia at codeweavers.com Wed Oct 5 04:17:03 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Wed, 5 Oct 2016 11:17:03 +0200 Subject: [PATCH 1/7] wined3d: Store pointer to device in wined3d_context. Message-ID: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/arb_program_shader.c | 27 +++++++++++++-------------- dlls/wined3d/ati_fragment_shader.c | 2 +- dlls/wined3d/context.c | 9 +++++---- dlls/wined3d/glsl_shader.c | 2 +- dlls/wined3d/state.c | 20 ++++++++++---------- dlls/wined3d/utils.c | 4 ++-- dlls/wined3d/wined3d_private.h | 3 ++- 7 files changed, 34 insertions(+), 33 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 87794ea..e00f981 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -732,7 +732,8 @@ static void shader_arb_update_float_vertex_constants(struct wined3d_device *devi /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active * context. On a context switch the old context will be fully dirtified */ - if (!context || context->swapchain->device != device) return; + if (!context || context->device != device) + return; memset(priv->vshader_const_dirty + start, 1, sizeof(*priv->vshader_const_dirty) * count); priv->highest_dirty_vs_const = max(priv->highest_dirty_vs_const, start + count); @@ -745,7 +746,8 @@ static void shader_arb_update_float_pixel_constants(struct wined3d_device *devic /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active * context. On a context switch the old context will be fully dirtified */ - if (!context || context->swapchain->device != device) return; + if (!context || context->device != device) + return; memset(priv->pshader_const_dirty + start, 1, sizeof(*priv->pshader_const_dirty) * count); priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, start + count); @@ -5051,10 +5053,7 @@ static void shader_arb_free_context_data(struct wined3d_context *context) { struct shader_arb_priv *priv; - if (!context->swapchain) - return; - - priv = context->swapchain->device->shader_priv; + priv = context->device->shader_priv; if (priv->last_context == context) priv->last_context = NULL; } @@ -5948,8 +5947,8 @@ static DWORD arbfp_get_emul_mask(const struct wined3d_gl_info *gl_info) static void state_texfactor_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_device *device = context->device; struct wined3d_color color; if (device->shader_backend == &arb_program_shader_backend) @@ -5975,8 +5974,8 @@ static void state_tss_constant_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_device *device = context->device; struct wined3d_color color; if (device->shader_backend == &arb_program_shader_backend) @@ -6002,8 +6001,8 @@ static void state_tss_constant_arbfp(struct wined3d_context *context, static void state_arb_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_device *device = context->device; float col[4]; if (device->shader_backend == &arb_program_shader_backend) @@ -6037,8 +6036,8 @@ static void state_arb_specularenable(struct wined3d_context *context, static void set_bumpmat_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_device *device = context->device; float mat[2][2]; context->constant_update_mask |= WINED3D_SHADER_CONST_PS_BUMP_ENV; @@ -6068,8 +6067,8 @@ static void tex_bumpenvlum_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_device *device = context->device; float param[4]; context->constant_update_mask |= WINED3D_SHADER_CONST_PS_BUMP_ENV; @@ -6127,10 +6126,10 @@ static void alpha_test_arbfp(struct wined3d_context *context, const struct wined static void color_key_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - struct wined3d_device *device = context->swapchain->device; + const struct wined3d_texture *texture = state->textures[0]; const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_device *device = context->device; struct wined3d_color float_key[2]; - const struct wined3d_texture *texture = state->textures[0]; if (!texture) return; @@ -6682,8 +6681,8 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con static void fragment_prog_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_device *device = context->device; struct shader_arb_priv *priv = device->fragment_priv; BOOL use_pshader = use_ps(state); struct ffp_frag_settings settings; diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index 7a04f76..04ff803 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -1012,7 +1012,7 @@ static void atifs_stage_constant(struct wined3d_context *context, const struct w static void set_tex_op_atifs(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_device *device = context->swapchain->device; + const struct wined3d_device *device = context->device; const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_d3d_info *d3d_info = context->d3d_info; struct atifs_context_private_data *ctx_priv = context->fragment_pipe_data; diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index fa47850..e8d9abc 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1827,6 +1827,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, context_invalidate_state(ret, state); } + ret->device = device; ret->swapchain = swapchain; ret->current_rt.texture = target; ret->current_rt.sub_resource_idx = 0; @@ -2380,7 +2381,7 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint if (old_texture_type != target) { - const struct wined3d_device *device = context->swapchain->device; + const struct wined3d_device *device = context->device; switch (old_texture_type) { @@ -3307,8 +3308,8 @@ static void context_load_shader_resources(struct wined3d_context *context, const static void context_bind_shader_resources(struct wined3d_context *context, const struct wined3d_state *state) { - const struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_device *device = context->device; struct wined3d_shader_sampler_map_entry *entry; struct wined3d_shader_resource_view *view; struct wined3d_sampler *sampler; @@ -3536,7 +3537,7 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str { if (current_context && current_context->current_rt.texture - && current_context->swapchain->device == device) + && current_context->device == device) { target_texture = current_context->current_rt.texture; target_sub_resource_idx = current_context->current_rt.sub_resource_idx; @@ -3569,7 +3570,7 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str /* Stay with the current context if possible. Otherwise use the * context for the primary swapchain. */ - if (current_context && current_context->swapchain->device == device) + if (current_context && current_context->device == device) context = current_context; else context = swapchain_get_context(device->swapchains[0]); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 0a7af72..3d5e03f 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1160,7 +1160,7 @@ static void shader_glsl_ffp_vertex_normalmatrix_uniform(const struct wined3d_con return; get_modelview_matrix(context, state, 0, &mv); - if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_FFP_LIGHTING) + if (context->device->wined3d->flags & WINED3D_LEGACY_FFP_LIGHTING) invert_matrix_3d(&mv, &mv); else invert_matrix(&mv, &mv); diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 3b96acc..0333dd4 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1712,7 +1712,7 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3 gl_info->gl_ops.gl.p_glEnable(GL_POLYGON_OFFSET_FILL); checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)"); - if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS) + if (context->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS) { float bias = -(float)const_bias.d; gl_info->gl_ops.gl.p_glPolygonOffset(bias, bias); @@ -3620,7 +3620,7 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state } else { - struct wined3d_device *device = context->swapchain->device; + struct wined3d_device *device = context->device; struct wined3d_sampler *sampler; struct wine_rb_entry *entry; @@ -3841,8 +3841,8 @@ static void state_vertexblend_w(struct wined3d_context *context, const struct wi static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND]; - struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_device *device = context->device; static unsigned int once; switch (val) @@ -3934,7 +3934,7 @@ static void transform_view(struct wined3d_context *context, const struct wined3d transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))); /* Avoid looping over a number of matrices if the app never used the functionality */ - if (context->swapchain->device->vertexBlendUsed) + if (context->device->vertexBlendUsed) { for (k = 1; k < gl_info->limits.blends; ++k) { @@ -4653,7 +4653,7 @@ static void viewport_miscpart_cc(struct wined3d_context *context, { const struct wined3d_rendertarget_view *depth_stencil = state->fb->depth_stencil; const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; - float pixel_center_offset = context->swapchain->device->wined3d->flags + float pixel_center_offset = context->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER ? 0.5f : 0.0f; const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_viewport vp = state->viewport; @@ -5870,15 +5870,15 @@ static unsigned int num_handlers(const APPLYSTATEFUNC *funcs) static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id); - context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id); + context->device->multistate_funcs[state_id][0](context, state, state_id); + context->device->multistate_funcs[state_id][1](context, state, state_id); } static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id); - context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id); - context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id); + context->device->multistate_funcs[state_id][0](context, state, state_id); + context->device->multistate_funcs[state_id][1](context, state, state_id); + context->device->multistate_funcs[state_id][2](context, state, state_id); } static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info, diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 173b028..e65907a 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -4513,7 +4513,7 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w * driver, but small enough to prevent it from interfering with any * anti-aliasing. */ - if (!clip_control && context->swapchain->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) + if (!clip_control && context->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) center_offset = 63.0f / 64.0f; else center_offset = -1.0f / 64.0f; @@ -4682,7 +4682,7 @@ static void compute_texture_matrix(const struct wined3d_gl_info *gl_info, const void get_texture_matrix(const struct wined3d_context *context, const struct wined3d_state *state, unsigned int tex, struct wined3d_matrix *mat) { - const struct wined3d_device *device = context->swapchain->device; + const struct wined3d_device *device = context->device; const struct wined3d_gl_info *gl_info = context->gl_info; BOOL generated = (state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 851c914..08e9120 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1462,6 +1462,7 @@ struct wined3d_context DWORD numDirtyEntries; DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */ + struct wined3d_device *device; struct wined3d_swapchain *swapchain; struct { @@ -3522,7 +3523,7 @@ static inline void shader_get_position_fixup(const struct wined3d_context *conte { float center_offset; - if (context->swapchain->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) + if (context->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) center_offset = 63.0f / 64.0f; else center_offset = -1.0f / 64.0f; -- 2.7.3 From jkucia at codeweavers.com Wed Oct 5 04:17:04 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Wed, 5 Oct 2016 11:17:04 +0200 Subject: [PATCH 2/7] wined3d: Avoid using "context->swapchain" in context_update_window(). In-Reply-To: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> References: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1475659029-16333-2-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/context.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index e8d9abc..f249587 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1114,18 +1114,18 @@ static void context_restore_gl_context(const struct wined3d_gl_info *gl_info, HD } } -static void context_update_window(struct wined3d_context *context) +static void context_update_window(struct wined3d_context *context, HWND win_handle) { - if (context->win_handle == context->swapchain->win_handle) + if (context->win_handle == win_handle) return; TRACE("Updating context %p window from %p to %p.\n", - context, context->win_handle, context->swapchain->win_handle); + context, context->win_handle, win_handle); if (context->hdc) wined3d_release_dc(context->win_handle, context->hdc); - context->win_handle = context->swapchain->win_handle; + context->win_handle = win_handle; context->hdc_is_private = FALSE; context->hdc_has_format = FALSE; context->needs_set = 1; @@ -3519,6 +3519,7 @@ static void context_setup_target(struct wined3d_context *context, struct wined3d_context *context_acquire(const struct wined3d_device *device, struct wined3d_surface *target) { struct wined3d_context *current_context = context_get_current(); + struct wined3d_swapchain *swapchain = NULL; struct wined3d_texture *target_texture; unsigned int target_sub_resource_idx; struct wined3d_context *context; @@ -3558,11 +3559,11 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str { context = current_context; } - else if (target_texture->swapchain) + else if ((swapchain = target_texture->swapchain)) { TRACE("Rendering onscreen.\n"); - context = swapchain_get_context(target_texture->swapchain); + context = swapchain_get_context(swapchain); } else { @@ -3571,13 +3572,19 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str /* Stay with the current context if possible. Otherwise use the * context for the primary swapchain. */ if (current_context && current_context->device == device) + { context = current_context; + } else - context = swapchain_get_context(device->swapchains[0]); + { + swapchain = device->swapchains[0]; + context = swapchain_get_context(swapchain); + } } context_enter(context); - context_update_window(context); + if (swapchain) + context_update_window(context, swapchain->win_handle); context_setup_target(context, target_texture, target_sub_resource_idx); if (!context->valid) return context; -- 2.7.3 From jkucia at codeweavers.com Wed Oct 5 04:17:05 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Wed, 5 Oct 2016 11:17:05 +0200 Subject: [PATCH 3/7] wined3d: Avoid trying to get backup DC when context is no longer associated with swapchain. In-Reply-To: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> References: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1475659029-16333-3-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index f249587..89cc9ce 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1069,7 +1069,7 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx) * a swapchain, so we can't use the swapchain to get a backup dc. To * make this work windowless contexts would need to be handled by the * device. */ - if (ctx->destroyed) + if (ctx->destroyed || !swapchain) { FIXME("Unable to get backup dc for destroyed context %p.\n", ctx); context_set_current(NULL); -- 2.7.3 From jkucia at codeweavers.com Wed Oct 5 04:17:06 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Wed, 5 Oct 2016 11:17:06 +0200 Subject: [PATCH 4/7] wined3d: Call context_destroy() directly if context is not associated with swapchain. In-Reply-To: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> References: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1475659029-16333-4-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index f2dfac7..90d0008 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4570,7 +4570,10 @@ static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d while (device->context_count) { - swapchain_destroy_contexts(device->contexts[0]->swapchain); + if (device->contexts[0]->swapchain) + swapchain_destroy_contexts(device->contexts[0]->swapchain); + else + context_destroy(device, device->contexts[0]); } HeapFree(GetProcessHeap(), 0, swapchain->context); -- 2.7.3 From jkucia at codeweavers.com Wed Oct 5 04:17:07 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Wed, 5 Oct 2016 11:17:07 +0200 Subject: [PATCH 5/7] wined3d: Avoid destroying active contexts. In-Reply-To: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> References: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1475659029-16333-5-git-send-email-jkucia@codeweavers.com> This commit fixes a problem which can be observed in d3d10core and d3d11 tests while a device is destroyed in test_swapchain_flip(). When a swapchain is destroyed all contexts associated with this swapchain are destroyed. A context is destroyed even if it is active. This might lead to using a destroyed context. In order to fix this the destruction of context is delayed until leaving the last level. Signed-off-by: Józef Kucia --- Ideally, a pointer to a swapchain would be completely removed from struct wined3d_context. There are still two places which use "context->swapchain" unsafely: surface_get_drawable_size() and surface_load_ds_location(). If one of this function gets called with a context marked for delayed destruction we'll get a NULL pointer dereference (previously it would access freed memory). --- dlls/wined3d/context.c | 17 +++++++++++++++++ dlls/wined3d/device.c | 6 +----- dlls/wined3d/wined3d_private.h | 3 ++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 89cc9ce..394a2dc 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1354,6 +1354,12 @@ void context_release(struct wined3d_context *context) context->restore_ctx = NULL; context->restore_dc = NULL; } + + if (context->destroy_delayed) + { + TRACE("Destroying context %p.\n", context); + context_destroy(context->device, context); + } } } @@ -2012,6 +2018,17 @@ void context_destroy(struct wined3d_device *device, struct wined3d_context *cont TRACE("Destroying ctx %p\n", context); + /* We delay destroying a context when it is active. The context_release() + * function invokes context_destroy() again while leaving the last level. */ + if (context->level) + { + TRACE("Delaying destruction of context %p.\n", context); + context->destroy_delayed = 1; + /* FIXME: Get rid of a pointer to swapchain from wined3d_context. */ + context->swapchain = NULL; + return; + } + if (context->tid == GetCurrentThreadId() || !context->current) { context_destroy_gl_resources(context); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 90d0008..1c8cb90 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1185,13 +1185,9 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) destroy_dummy_textures(device, gl_info); destroy_default_samplers(device); - /* Release the context again as soon as possible. In particular, - * releasing the render target views below may release the last reference - * to the swapchain associated with this context, which in turn will - * destroy the context. */ context_release(context); - /* Release the buffers (with sanity checks)*/ + /* Release the buffers (with sanity checks) */ if (device->onscreen_depth_stencil) { surface = device->onscreen_depth_stencil; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 08e9120..3887f91 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1497,7 +1497,8 @@ struct wined3d_context DWORD hdc_is_private : 1; DWORD hdc_has_format : 1; /* only meaningful if hdc_is_private */ DWORD update_shader_resource_bindings : 1; - DWORD padding : 14; + DWORD destroy_delayed : 1; + DWORD padding : 13; DWORD last_swizzle_map; /* MAX_ATTRIBS, 16 */ DWORD shader_update_mask; DWORD constant_update_mask; -- 2.7.3 From jkucia at codeweavers.com Wed Oct 5 04:17:08 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Wed, 5 Oct 2016 11:17:08 +0200 Subject: [PATCH resend 6/7] wined3d: Pass context to destroy_default_samplers(). In-Reply-To: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> References: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1475659029-16333-6-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/device.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 1c8cb90..94ea4c5 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -827,9 +827,9 @@ static void create_default_samplers(struct wined3d_device *device, struct wined3 } /* Context activation is done by the caller. */ -static void destroy_default_samplers(struct wined3d_device *device) +static void destroy_default_samplers(struct wined3d_device *device, struct wined3d_context *context) { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + const struct wined3d_gl_info *gl_info = context->gl_info; if (gl_info->supported[ARB_SAMPLER_OBJECTS]) { @@ -1183,7 +1183,7 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) device->blitter->free_private(device); device->shader_backend->shader_free_private(device); destroy_dummy_textures(device, gl_info); - destroy_default_samplers(device); + destroy_default_samplers(device, context); context_release(context); @@ -4560,7 +4560,7 @@ static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d device->blitter->free_private(device); device->shader_backend->shader_free_private(device); destroy_dummy_textures(device, gl_info); - destroy_default_samplers(device); + destroy_default_samplers(device, context); context_release(context); -- 2.7.3 From jkucia at codeweavers.com Wed Oct 5 04:17:09 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Wed, 5 Oct 2016 11:17:09 +0200 Subject: [PATCH resend 7/7] wined3d: Pass context to destroy_dummy_textures(). In-Reply-To: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> References: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1475659029-16333-7-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/device.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 94ea4c5..de6d5a4 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -772,8 +772,10 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_ } /* Context activation is done by the caller. */ -static void destroy_dummy_textures(struct wined3d_device *device, const struct wined3d_gl_info *gl_info) +static void destroy_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; + if (gl_info->supported[EXT_TEXTURE_ARRAY]) gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->dummy_textures.tex_2d_array); @@ -1182,7 +1184,7 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) /* Destroy the shader backend. Note that this has to happen after all shaders are destroyed. */ device->blitter->free_private(device); device->shader_backend->shader_free_private(device); - destroy_dummy_textures(device, gl_info); + destroy_dummy_textures(device, context); destroy_default_samplers(device, context); context_release(context); @@ -4559,7 +4561,7 @@ static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d device->blitter->free_private(device); device->shader_backend->shader_free_private(device); - destroy_dummy_textures(device, gl_info); + destroy_dummy_textures(device, context); destroy_default_samplers(device, context); context_release(context); -- 2.7.3 From aric at codeweavers.com Wed Oct 5 08:01:38 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 5 Oct 2016 08:01:38 -0500 Subject: [PATCH v2] winebus.sys: Implement common IRP_MJ_POWER handling Message-ID: v2: Suggestions from Sebastian Lackner Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_udev.c | 1 + dlls/winebus.sys/main.c | 21 +++++++++++++++++++++ 3 files changed, 23 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: v2-0001-winebus.sys-Implement-common-IRP_MJ_POWER-handling.txt Type: text/x-patch Size: 2414 bytes Desc: not available URL: From berencamlost at msn.com Wed Oct 5 08:45:53 2016 From: berencamlost at msn.com (Kim Malmo) Date: Wed, 5 Oct 2016 13:45:53 +0000 Subject: [PATCH] po: Update Norwegian translation Message-ID: Signed-off-by: Kim Malmo --- po/nb_NO.po | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/po/nb_NO.po b/po/nb_NO.po index def5854..55180b7 100644 --- a/po/nb_NO.po +++ b/po/nb_NO.po @@ -8108,7 +8108,7 @@ msgstr "Min datamaskin" #: shell32.rc:159 msgid "Control Panel" -msgstr "Control Panel" +msgstr "Kontrollpanel" #: shell32.rc:166 msgid "Select" @@ -8462,7 +8462,7 @@ msgstr "%d byte" #: shlwapi.rc:31 msgctxt "time unit: hours" msgid " hr" -msgstr " hr" +msgstr " t" #: shlwapi.rc:32 msgctxt "time unit: minutes" @@ -8472,7 +8472,7 @@ msgstr " min" #: shlwapi.rc:33 msgctxt "time unit: seconds" msgid " sec" -msgstr " sec" +msgstr " sek" #: urlmon.rc:32 wininet.rc:77 msgid "Security Warning" @@ -10217,7 +10217,7 @@ msgstr "" "XCOPY\t\tKopierer kildefiler eller et katalogtre til et mål\n" "EXIT\t\tAvslutter CMD\n" "\n" -"Skriv HELP for mer informasjon om kommandoene ovenfor\n" +"Skriv HELP for mer informasjon om kommandoene ovenfor.\n" #: cmd.rc:353 msgid "Are you sure?" @@ -11936,8 +11936,8 @@ msgstr "" " /? Vis denne informasjonen og avslutt.\n" " [filnavn] Plasseringen til filen som inneholder registerinformasjonen " "som\n" -" skal importeres. Når brukt med [/E], spesifiserer dette \n" -" alternativet plasseringen hvor registerinformasjonen vil \n" +" skal importeres. Når brukt med [/E], spesifiserer dette\n" +" alternativet plasseringen hvor registerinformasjonen vil\n" " bli eksportert.\n" " [reg_key] Registernøkkelen som skal modifiseres.\n" "\n" @@ -11988,7 +11988,7 @@ msgid "" "encountered at '%1'.\n" msgstr "" "regedit: Kan ikke konvertere heksadesimale data. En ugyldig verdi " -"inntraffved \"%1\".\n" +"inntraff ved \"%1\".\n" #: regedit.rc:370 msgid "regedit: Unrecognized escape sequence [\\%1!c!]\n" @@ -12207,6 +12207,7 @@ msgid "" "regsvr32: Invalid or unrecognized switch [%1]\n" "\n" msgstr "regsvr32: Ugyldig eller ukjent bryter [%1]\n" +"\n" #: regsvr32.rc:42 msgid "regsvr32: Failed to load DLL '%1'\n" -- 1.9.1 From piotr at codeweavers.com Wed Oct 5 10:04:48 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Wed, 5 Oct 2016 17:04:48 +0200 Subject: msvcp110: Fix num_get structure layout Message-ID: Signed-off-by: Piotr Caban --- dlls/msvcp90/locale.c | 42 ++++++++++++++++++++++++++++++------------ dlls/msvcp90/msvcp90.h | 2 ++ 2 files changed, 32 insertions(+), 12 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-msvcp110-Fix-num_get-structure-layout.txt Type: text/x-patch Size: 5434 bytes Desc: not available URL: From nsivov at codeweavers.com Wed Oct 5 10:33:53 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Wed, 5 Oct 2016 18:33:53 +0300 Subject: [PATCH] d2d1/tests: Initial tests for bitmap render target Message-ID: <20161005153353.6007-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/d2d1/tests/d2d1.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index c9e1692..8cfe5d2 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -17,6 +17,7 @@ */ #define COBJMACROS +#include #include #include "d2d1.h" #include "wincrypt.h" @@ -76,6 +77,12 @@ static void set_size_u(D2D1_SIZE_U *size, unsigned int w, unsigned int h) size->height = h; } +static void set_size_f(D2D1_SIZE_F *size, float w, float h) +{ + size->width = w; + size->height = h; +} + static void set_matrix_identity(D2D1_MATRIX_3X2_F *matrix) { matrix->_11 = 1.0f; @@ -115,6 +122,19 @@ static void translate_matrix(D2D1_MATRIX_3X2_F *matrix, float x, float y) matrix->_32 += x * matrix->_12 + y * matrix->_22; } +static inline BOOL float_eq(FLOAT left, FLOAT right) +{ + int x = *(int *)&left; + int y = *(int *)&right; + + if (x < 0) + x = INT_MIN - x; + if (y < 0) + y = INT_MIN - y; + + return abs(x - y) <= 8; +} + static BOOL compare_sha1(void *data, unsigned int pitch, unsigned int bpp, unsigned int w, unsigned int h, const char *ref_sha1) { @@ -2881,6 +2901,155 @@ static void test_hwnd_target(void) ID2D1Factory_Release(factory); } +static void test_bitmap_target(void) +{ + D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc; + D2D1_SIZE_U pixel_size, pixel_size2; + D2D1_RENDER_TARGET_PROPERTIES desc; + ID2D1HwndRenderTarget *hwnd_rt; + ID2D1Bitmap *bitmap, *bitmap2; + ID2D1BitmapRenderTarget *rt; + D2D1_SIZE_F size, size2; + ID2D1Factory *factory; + ID3D10Device1 *device; + float dpi[2], dpi2[2]; + D2D1_COLOR_F color; + ULONG refcount; + HRESULT hr; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + ID3D10Device1_Release(device); + + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); + ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr); + + desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + desc.dpiX = 0.0f; + desc.dpiY = 0.0f; + desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0); + ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n"); + hwnd_rt_desc.pixelSize.width = 64; + hwnd_rt_desc.pixelSize.height = 64; + hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE; + + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &hwnd_rt); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt); +todo_wine + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + if (FAILED(hr)) + { + ID2D1HwndRenderTarget_Release(hwnd_rt); + DestroyWindow(hwnd_rt_desc.hwnd); + ID2D1Factory_Release(factory); + return; + } + + /* See if parent target is referenced. */ + ID2D1HwndRenderTarget_AddRef(hwnd_rt); + refcount = ID2D1HwndRenderTarget_Release(hwnd_rt); + ok(refcount == 1, "Target should not have been referenced, got %u.\n", refcount); + + /* Size was not specified, should match parent. */ + pixel_size = ID2D1HwndRenderTarget_GetPixelSize(hwnd_rt); + pixel_size2 = ID2D1BitmapRenderTarget_GetPixelSize(rt); + ok(!memcmp(&pixel_size, &pixel_size2, sizeof(pixel_size)), "Got target pixel size mismatch.\n"); + + size = ID2D1HwndRenderTarget_GetSize(hwnd_rt); + size2 = ID2D1BitmapRenderTarget_GetSize(rt); + ok(!memcmp(&size, &size2, sizeof(size)), "Got target DIP size mismatch.\n"); + + ID2D1HwndRenderTarget_GetDpi(hwnd_rt, dpi, dpi + 1); + ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1); + ok(!memcmp(dpi, dpi2, sizeof(dpi)), "Got dpi mismatch.\n"); + + ID2D1BitmapRenderTarget_Release(rt); + + /* Pixel size specified. */ + set_size_u(&pixel_size, 32, 32); + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, &pixel_size, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + pixel_size2 = ID2D1BitmapRenderTarget_GetPixelSize(rt); + ok(!memcmp(&pixel_size, &pixel_size2, sizeof(pixel_size)), "Got target pixel size mismatch.\n"); + + ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1); + ok(!memcmp(dpi, dpi2, sizeof(dpi)), "Got dpi mismatch.\n"); + + ID2D1BitmapRenderTarget_Release(rt); + + /* Both pixel size and DIP size are specified. */ + set_size_u(&pixel_size, 128, 128); + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, &size, &pixel_size, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + /* Doubled pixel size dimensions with the same DIP size give doubled dpi. */ + ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1); + ok(dpi[0] == dpi2[0] / 2.0f && dpi[1] == dpi2[1] / 2.0f, "Got dpi mismatch.\n"); + + ID2D1BitmapRenderTarget_Release(rt); + + /* DIP size is specified, fractional. */ + set_size_f(&size, 70.4f, 70.5f); + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, &size, NULL, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(rt); + ok(pixel_size.width == ceilf(size.width) && pixel_size.height == ceilf(size.height), "Wrong pixel size %ux%u\n", + pixel_size.width, pixel_size.height); + + ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1); + dpi[0] *= pixel_size.width / size.width; + dpi[1] *= pixel_size.height / size.height; + + ok(float_eq(dpi[0], dpi2[0]) && float_eq(dpi[1], dpi2[1]), "Got dpi mismatch.\n"); + + ID2D1HwndRenderTarget_Release(hwnd_rt); + + /* Check if GetBitmap() returns same instance. */ + hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap); + ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr); + hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap2); + ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr); + ok(bitmap == bitmap2, "Got different bitmap instances.\n"); + + /* Draw something, see if bitmap instance is retained. */ + ID2D1BitmapRenderTarget_BeginDraw(rt); + set_color(&color, 1.0f, 1.0f, 0.0f, 1.0f); + ID2D1BitmapRenderTarget_Clear(rt, &color); + hr = ID2D1BitmapRenderTarget_EndDraw(rt, NULL, NULL); + ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr); + + ID2D1Bitmap_Release(bitmap2); + hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap2); + ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr); + ok(bitmap == bitmap2, "Got different bitmap instances.\n"); + + ID2D1Bitmap_Release(bitmap); + ID2D1Bitmap_Release(bitmap2); + + refcount = ID2D1BitmapRenderTarget_Release(rt); + ok(!refcount, "Target should be released, got %u.\n", refcount); + + DestroyWindow(hwnd_rt_desc.hwnd); + ID2D1Factory_Release(factory); +} + START_TEST(d2d1) { test_clip(); @@ -2897,4 +3066,5 @@ START_TEST(d2d1) test_draw_text_layout(); test_dc_target(); test_hwnd_target(); + test_bitmap_target(); } -- 2.9.3 From frederic.delanoy at gmail.com Wed Oct 5 11:57:13 2016 From: frederic.delanoy at gmail.com (=?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delanoy?=) Date: Wed, 5 Oct 2016 18:57:13 +0200 Subject: [website] French translation for release 1.9.20 Message-ID: <20161005165713.31235-1-frederic.delanoy@gmail.com> Signed-off-by: Frédéric Delanoy --- news/fr/2016100101.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 news/fr/2016100101.xml diff --git a/news/fr/2016100101.xml b/news/fr/2016100101.xml new file mode 100644 index 0000000..79160bd --- /dev/null +++ b/news/fr/2016100101.xml @@ -0,0 +1,14 @@ + +1er octobre 2016 +Sortie de Wine 1.9.20 + +

La version de développement 1.9.20 de Wine est disponible.

+

Nouveautés de cette version : +

    +
  • Réimplementation de l'API du presse-papiers.
  • +
  • Traitement des messages dans WebServices.
  • +
  • Beaucoup de bibliothèques de jeux d'API supplémentaires.
  • +
  • Diverses corrections de bugs.
  • +

+

Le code source est disponible dès à présent. Les paquets binaires sont en cours de construction, et apparaîtront sous peu sur leurs sites de téléchargement respectifs. +

-- 2.10.0 From ale.goujon at gmail.com Wed Oct 5 13:51:52 2016 From: ale.goujon at gmail.com (GOUJON Alexandre) Date: Wed, 5 Oct 2016 20:51:52 +0200 Subject: [PATCH] msvcrt: Implement 64-bit version of __std_type_info_hash (try 2) Message-ID: <1475693512-10507-1-git-send-email-ale.goujon@gmail.com> Fixes https://bugs.winehq.org/show_bug.cgi?id=41437 Signed-off-by: GOUJON Alexandre --- dlls/msvcrt/cpp.c | 19 +++++++++++++++---- dlls/ucrtbase/tests/cpp.c | 9 ++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/dlls/msvcrt/cpp.c b/dlls/msvcrt/cpp.c index 0ffe61e..f7127a3 100644 --- a/dlls/msvcrt/cpp.c +++ b/dlls/msvcrt/cpp.c @@ -1591,20 +1591,31 @@ void CDECL MSVCRT_type_info_destroy_list(SLIST_HEADER *header) /****************************************************************** * __std_type_info_hash (UCRTBASE.@) - * - * TODO: 64-bit version of the function uses different constants */ MSVCRT_size_t CDECL MSVCRT_type_info_hash(const type_info140 *ti) { - MSVCRT_size_t hash = 0x811c9dc5; + MSVCRT_size_t hash, fnv_prime; const char *p; +#ifdef _WIN64 + hash = 0xcbf29ce484222325; + fnv_prime = 0x100000001b3; +#else + hash = 0x811c9dc5; + fnv_prime = 0x1000193; +#endif + TRACE("(%p)->%s\n", ti, ti->mangled); for(p = ti->mangled+1; *p; p++) { hash ^= *p; - hash *= 0x1000193; + hash *= fnv_prime; } + +#ifdef _WIN64 + hash ^= hash >> 32; +#endif + return hash; } #endif diff --git a/dlls/ucrtbase/tests/cpp.c b/dlls/ucrtbase/tests/cpp.c index 1a01fea..c0687ea 100644 --- a/dlls/ucrtbase/tests/cpp.c +++ b/dlls/ucrtbase/tests/cpp.c @@ -163,19 +163,22 @@ static void test___std_type_info(void) ti1.mangled[2] = 0; hash1 = p___std_type_info_hash(&ti1); #ifdef _WIN64 - todo_wine ok(hash1 == 0xcbf29ce44fd0bfc1, "hash = %p\n", (void*)hash1); + ok(hash1 == 0xcbf29ce44fd0bfc1, "hash = %p\n", (void*)hash1); #else ok(hash1 == 0x811c9dc5, "hash = %p\n", (void*)hash1); #endif ti1.mangled[0] = 1; hash2 = p___std_type_info_hash(&ti1); - ok(hash1 == hash2, "hash1 != hash2 (first char not ignorred)\n"); + ok(hash1 == hash2, "hash1 != hash2 (first char not ignored)\n"); ti1.mangled[1] = 1; hash1 = p___std_type_info_hash(&ti1); - if(sizeof(void*) == sizeof(int)) +#ifdef _WIN64 + ok(hash1 == 0xaf63bc4c29620a60, "hash = %p\n", (void*)hash1); +#else ok(hash1 == 0x40c5b8c, "hash = %p\n", (void*)hash1); +#endif ok(hash1 != hash2, "hash1 == hash2 for different strings\n"); ti1.mangled[1] = 2; -- 2.7.4 From jacek at codeweavers.com Wed Oct 5 14:27:06 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:27:06 +0200 Subject: [PATCH 01/16] kernel32/tests: Added GetNamedPipeInfo tests. Message-ID: <338d6634-6641-7115-665b-292b75189344@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/kernel32/tests/pipe.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-kernel32-tests-Added-GetNamedPipeInfo-tests.diff Type: text/x-patch Size: 3575 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:27:17 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:27:17 +0200 Subject: [PATCH 02/16] rpcrt4: Restore original error code when ReadFile fails with ERROR_MORE_DATA. Message-ID: <05305575-438a-704a-b472-286a74e684ed@codeweavers.com> From: Sebastian Lackner Signed-off-by: Jacek Caban --- dlls/rpcrt4/rpc_transport.c | 2 ++ 1 file changed, 2 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-rpcrt4-Restore-original-error-code-when-ReadFile-fail.diff Type: text/x-patch Size: 590 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:27:32 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:27:32 +0200 Subject: [PATCH 03/16] server: Store associated async queue list in fd struct. Message-ID: <705a1a21-7504-a754-37fc-3f2500ea240b@codeweavers.com> Signed-off-by: Jacek Caban --- This is needed for patch 8 to avoid adding new entry to fd_ops. Instead, I removed one entry in patch 5. server/async.c | 17 +++++++++++++++-- server/fd.c | 13 ++++++++++--- server/file.h | 2 ++ 3 files changed, 27 insertions(+), 5 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0003-server-Store-associated-async-queue-list-in-fd-struct.diff Type: text/x-patch Size: 5010 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:27:50 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:27:50 +0200 Subject: [PATCH 04/16] server: Use queue list in default_fd_cancel_async. Message-ID: <7a02a9fa-b8ce-f19d-4da6-0625094a18df@codeweavers.com> Signed-off-by: Jacek Caban --- server/async.c | 24 ++++++++++++++---------- server/fd.c | 7 +------ server/file.h | 2 +- server/sock.c | 16 +--------------- 4 files changed, 17 insertions(+), 32 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0004-server-Use-queue-list-in-default_fd_cancel_async.diff Type: text/x-patch Size: 5001 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:28:04 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:28:04 +0200 Subject: [PATCH 05/16] server: Removed no longer needed cancel_async from fd_ops. Message-ID: Signed-off-by: Jacek Caban --- server/change.c | 3 +-- server/console.c | 3 +-- server/device.c | 3 +-- server/fd.c | 8 +------- server/file.c | 3 +-- server/file.h | 3 --- server/mailslot.c | 9 +++------ server/mapping.c | 3 +-- server/named_pipe.c | 9 +++------ server/serial.c | 3 +-- server/sock.c | 6 ++---- 11 files changed, 15 insertions(+), 38 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0005-server-Removed-no-longer-needed-cancel_async-from-fd_.diff Type: text/x-patch Size: 9177 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:28:17 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:28:17 +0200 Subject: [PATCH 06/16] server: Introduced iosb struct for server-side IO_STATUS_BLOCK representation and use it in irp_call. Message-ID: Signed-off-by: Jacek Caban --- server/async.c | 34 +++++++++++++++++++++++++++++++++ server/device.c | 58 +++++++++++++++++++++++++-------------------------------- server/file.h | 14 ++++++++++++++ 3 files changed, 73 insertions(+), 33 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0006-server-Introduced-iosb-struct-for-server-side-IO_STAT.diff Type: text/x-patch Size: 7874 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:28:25 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:28:25 +0200 Subject: [PATCH 07/16] server: Store iosb in async object. Message-ID: Signed-off-by: Jacek Caban --- server/async.c | 15 ++++++++++++++- server/change.c | 2 +- server/device.c | 2 +- server/fd.c | 6 +++--- server/file.h | 5 +++-- server/mailslot.c | 2 +- server/named_pipe.c | 6 +++--- server/serial.c | 2 +- server/sock.c | 4 ++-- 9 files changed, 29 insertions(+), 15 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0007-server-Store-iosb-in-async-object.diff Type: text/x-patch Size: 9904 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:28:33 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:28:33 +0200 Subject: [PATCH 08/16] server: Use async object to transfer IRP result to client. Message-ID: Signed-off-by: Jacek Caban --- dlls/ntdll/file.c | 2 +- server/async.c | 21 ++++++++++++++++++++ server/device.c | 55 ++++------------------------------------------------- server/fd.c | 32 +++++++++++++++++++++++++++++++ server/file.h | 2 ++ server/protocol.def | 19 +++++++++--------- 6 files changed, 69 insertions(+), 62 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0008-server-Use-async-object-to-transfer-IRP-result-to-cli.diff Type: text/x-patch Size: 8117 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:28:46 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:28:46 +0200 Subject: [PATCH 09/16] server: Introduced new pipe_end struct containing common parts of pipe_client and pipe_server. Message-ID: <7e03bd6b-5eec-920b-38e9-3c096bd8a6d0@codeweavers.com> Signed-off-by: Jacek Caban --- server/named_pipe.c | 99 ++++++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 46 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0009-server-Introduced-new-pipe_end-struct-containing-comm.diff Type: text/x-patch Size: 11647 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:29:06 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:29:06 +0200 Subject: [PATCH 10/16] server: Moved server-independent parts of pipe_server_flush into separated function. Message-ID: <46fd73a7-e62e-ceac-961a-77dbd3309c46@codeweavers.com> Signed-off-by: Jacek Caban --- server/named_pipe.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0010-server-Moved-server-independent-parts-of-pipe_server_.diff Type: text/x-patch Size: 2150 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:29:25 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:29:25 +0200 Subject: [PATCH 11/16] server: Signal pipe server fd in create_pipe_server. Message-ID: <5827ad71-ccae-8259-ea98-c6556b741ee4@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/kernel32/tests/pipe.c | 8 ++++++++ server/named_pipe.c | 1 + 2 files changed, 9 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0011-server-Signal-pipe-server-fd-in-create_pipe_servr.diff Type: text/x-patch Size: 1412 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:31:06 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:31:06 +0200 Subject: [PATCH 12/16] server: Added support for message mode named pipes. Message-ID: Signed-off-by: Jacek Caban --- This is the most important patch in the series. It moves named pipe I/O to server so that we may properly and portably support message mode. The series is prepared in a way that makes this patch no-op for byte mode named pipes. Although code would be much nicer if we moved them as well, I believe that scope and impact of this change is already huge. The biggest disadvantage of this change is performance. Server calls will always be slower than plain syscalls. This patch intends to implement proper results first and performance could be improved in follow ups. Ideally a simple read()/write() with immediate result could take only one server call. For that: - ntdll handle cache will need to store information about server-side pseudo fds, so that we don't need to call get_handle_fd just to get an error every time we do read/write - server calls could transfer the result directly when possible, instead of using APCs. That requires handling overlapped events on client side. Those shouldn't be too hard and I intend to look at them. dlls/kernel32/tests/pipe.c | 74 ++----- dlls/ntdll/file.c | 7 +- dlls/ntdll/tests/file.c | 2 +- server/async.c | 9 + server/file.h | 1 + server/named_pipe.c | 497 ++++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 503 insertions(+), 87 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0012-server-Added-support-for-message-mode-named-pipes.diff Type: text/x-patch Size: 43926 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:31:26 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:31:26 +0200 Subject: [PATCH 14/16] kernel32/tests: Added more named pipe tests. Message-ID: <1403b166-7cae-bc55-628e-974828f0e0d7@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/kernel32/tests/pipe.c | 384 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 384 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0014-kernel32-tests-Added-more-named-pipe-tests.diff Type: text/x-patch Size: 17656 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:31:36 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:31:36 +0200 Subject: [PATCH 15/16] kernel32/tests: Added tests of real buffer size. Message-ID: Signed-off-by: Jacek Caban --- dlls/kernel32/tests/pipe.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0015-kernel32-tests-Added-tests-of-real-buffer-size.diff Type: text/x-patch Size: 2576 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:31:42 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:31:42 +0200 Subject: [PATCH 16/16] ntdll/tests: Added a test of using NtCancelIoEx on iosb associated with pipe listening. Message-ID: Signed-off-by: Jacek Caban --- dlls/ntdll/tests/pipe.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0016-ntdll-tests-Added-a-test-of-using-NtCancelIoEx-on-ios.diff Type: text/x-patch Size: 1993 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 5 14:31:51 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 5 Oct 2016 21:31:51 +0200 Subject: [PATCH 13/16] server: Added support for flushing client pipe. Message-ID: Signed-off-by: Jacek Caban --- server/named_pipe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0013-server-Added-support-for-flushing-client-pipe.diff Type: text/x-patch Size: 669 bytes Desc: not available URL: From sebastian at fds-team.de Wed Oct 5 15:19:45 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Wed, 5 Oct 2016 22:19:45 +0200 Subject: ntoskrnl.exe: Return STATUS_INVALID_DEVICE_REQUEST when calling unhandled driver function. Message-ID: Signed-off-by: Sebastian Lackner --- Tested on XP and Win2k3 (see https://newtestbot.winehq.org/JobDetails.pl?Key=26044). dlls/ntoskrnl.exe/ntoskrnl.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 522facf..0b5be33 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -884,6 +884,15 @@ static void build_driver_keypath( const WCHAR *name, UNICODE_STRING *keypath ) } +static NTSTATUS WINAPI unhandled_irp( DEVICE_OBJECT *device, IRP *irp ) +{ + TRACE( "(%p, %p)", device, irp ); + irp->IoStatus.u.Status = STATUS_INVALID_DEVICE_REQUEST; + IoCompleteRequest( irp, IO_NO_INCREMENT ); + return STATUS_INVALID_DEVICE_REQUEST; +} + + /*********************************************************************** * IoCreateDriver (NTOSKRNL.EXE.@) */ @@ -891,6 +900,7 @@ NTSTATUS WINAPI IoCreateDriver( UNICODE_STRING *name, PDRIVER_INITIALIZE init ) { struct wine_driver *driver; NTSTATUS status; + unsigned int i; TRACE("(%s, %p)\n", debugstr_us(name), init); @@ -909,24 +919,29 @@ NTSTATUS WINAPI IoCreateDriver( UNICODE_STRING *name, PDRIVER_INITIALIZE init ) driver->driver_obj.DriverExtension = &driver->driver_extension; driver->driver_extension.DriverObject = &driver->driver_obj; build_driver_keypath( driver->driver_obj.DriverName.Buffer, &driver->driver_extension.ServiceKeyName ); + for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) + driver->driver_obj.MajorFunction[i] = unhandled_irp; status = driver->driver_obj.DriverInit( &driver->driver_obj, &driver->driver_extension.ServiceKeyName ); - if (status) { RtlFreeUnicodeString( &driver->driver_obj.DriverName ); RtlFreeUnicodeString( &driver->driver_extension.ServiceKeyName ); RtlFreeHeap( GetProcessHeap(), 0, driver ); + return status; } - else + + for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { - EnterCriticalSection( &drivers_cs ); - if (wine_rb_put( &wine_drivers, &driver->driver_obj.DriverName, &driver->entry )) - ERR( "failed to insert driver %s in tree\n", debugstr_us(name) ); - LeaveCriticalSection( &drivers_cs ); + if (driver->driver_obj.MajorFunction[i]) continue; + driver->driver_obj.MajorFunction[i] = unhandled_irp; } - return status; + EnterCriticalSection( &drivers_cs ); + if (wine_rb_put( &wine_drivers, &driver->driver_obj.DriverName, &driver->entry )) + ERR( "failed to insert driver %s in tree\n", debugstr_us(name) ); + LeaveCriticalSection( &drivers_cs ); + return STATUS_SUCCESS; } -- 2.9.0 From sebastian at fds-team.de Wed Oct 5 16:30:10 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Wed, 5 Oct 2016 23:30:10 +0200 Subject: ntoskrnl.exe: Return STATUS_INVALID_DEVICE_REQUEST when calling unhandled driver function. (v2) Message-ID: <64678f88-9a60-4273-d10a-a4ab1a5f6d47@fds-team.de> Signed-off-by: Sebastian Lackner --- Tested on XP and Win2k3 (see https://newtestbot.winehq.org/JobDetails.pl?Key=26044). Changes in v2: * Add a missing \n... Oops ;) dlls/ntoskrnl.exe/ntoskrnl.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 522facf..cc6ea0b 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -884,6 +884,15 @@ static void build_driver_keypath( const WCHAR *name, UNICODE_STRING *keypath ) } +static NTSTATUS WINAPI unhandled_irp( DEVICE_OBJECT *device, IRP *irp ) +{ + TRACE( "(%p, %p)\n", device, irp ); + irp->IoStatus.u.Status = STATUS_INVALID_DEVICE_REQUEST; + IoCompleteRequest( irp, IO_NO_INCREMENT ); + return STATUS_INVALID_DEVICE_REQUEST; +} + + /*********************************************************************** * IoCreateDriver (NTOSKRNL.EXE.@) */ @@ -891,6 +900,7 @@ NTSTATUS WINAPI IoCreateDriver( UNICODE_STRING *name, PDRIVER_INITIALIZE init ) { struct wine_driver *driver; NTSTATUS status; + unsigned int i; TRACE("(%s, %p)\n", debugstr_us(name), init); @@ -909,24 +919,29 @@ NTSTATUS WINAPI IoCreateDriver( UNICODE_STRING *name, PDRIVER_INITIALIZE init ) driver->driver_obj.DriverExtension = &driver->driver_extension; driver->driver_extension.DriverObject = &driver->driver_obj; build_driver_keypath( driver->driver_obj.DriverName.Buffer, &driver->driver_extension.ServiceKeyName ); + for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) + driver->driver_obj.MajorFunction[i] = unhandled_irp; status = driver->driver_obj.DriverInit( &driver->driver_obj, &driver->driver_extension.ServiceKeyName ); - if (status) { RtlFreeUnicodeString( &driver->driver_obj.DriverName ); RtlFreeUnicodeString( &driver->driver_extension.ServiceKeyName ); RtlFreeHeap( GetProcessHeap(), 0, driver ); + return status; } - else + + for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { - EnterCriticalSection( &drivers_cs ); - if (wine_rb_put( &wine_drivers, &driver->driver_obj.DriverName, &driver->entry )) - ERR( "failed to insert driver %s in tree\n", debugstr_us(name) ); - LeaveCriticalSection( &drivers_cs ); + if (driver->driver_obj.MajorFunction[i]) continue; + driver->driver_obj.MajorFunction[i] = unhandled_irp; } - return status; + EnterCriticalSection( &drivers_cs ); + if (wine_rb_put( &wine_drivers, &driver->driver_obj.DriverName, &driver->entry )) + ERR( "failed to insert driver %s in tree\n", debugstr_us(name) ); + LeaveCriticalSection( &drivers_cs ); + return STATUS_SUCCESS; } -- 2.9.0 From matteo.mystral at gmail.com Wed Oct 5 18:49:01 2016 From: matteo.mystral at gmail.com (Matteo Bruni) Date: Thu, 6 Oct 2016 01:49:01 +0200 Subject: [PATCH 1/7] wined3d: Store pointer to device in wined3d_context. In-Reply-To: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> References: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> Message-ID: 2016-10-05 11:17 GMT+02:00 Józef Kucia : > Signed-off-by: Józef Kucia > --- > dlls/wined3d/arb_program_shader.c | 27 +++++++++++++-------------- > dlls/wined3d/ati_fragment_shader.c | 2 +- > dlls/wined3d/context.c | 9 +++++---- > dlls/wined3d/glsl_shader.c | 2 +- > dlls/wined3d/state.c | 20 ++++++++++---------- > dlls/wined3d/utils.c | 4 ++-- > dlls/wined3d/wined3d_private.h | 3 ++- > 7 files changed, 34 insertions(+), 33 deletions(-) I have an almost identical patch in my queue (quite far from the top though). Have my: Signed-off-by: Matteo Bruni From aric at codeweavers.com Wed Oct 5 21:51:54 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 5 Oct 2016 21:51:54 -0500 Subject: [PATCH] winebus.sys: Implement IOCTL_HID_GET_DEVICE_ATTRIBUTES for hid devices Message-ID: Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_udev.c | 1 + dlls/winebus.sys/main.c | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-winebus.sys-Implement-IOCTL_HID_GET_DEVICE_ATTRIBUTES-.txt Type: text/x-patch Size: 3281 bytes Desc: not available URL: From leslie_alistair at hotmail.com Thu Oct 6 03:41:17 2016 From: leslie_alistair at hotmail.com (Alistair Leslie-Hughes) Date: Thu, 6 Oct 2016 08:41:17 +0000 Subject: [PATCH] winspool.drv: Assign an empty port if not found in registry. Message-ID: Fixes: https://bugs.winehq.org/show_bug.cgi?id=33502 Signed-off-by: Alistair Leslie-Hughes --- dlls/winspool.drv/info.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c index 4dea531..26184c2 100644 --- a/dlls/winspool.drv/info.c +++ b/dlls/winspool.drv/info.c @@ -4318,6 +4318,18 @@ static BOOL WINSPOOL_GetPrinter_5(HKEY hkeyPrinter, PRINTER_INFO_5W *pi5, space = FALSE; *pcbNeeded += size; } + else + { + /* Assign an empty port */ + if(space && size <= left) { + pi5->pPortName = (LPWSTR)ptr; + *pi5->pPortName = '\0'; + ptr += sizeof(WCHAR); + left -= sizeof(WCHAR); + } else + space = FALSE; + *pcbNeeded += sizeof(WCHAR); + } if(pi5) { pi5->Attributes = get_dword_from_reg( hkeyPrinter, AttributesW ); pi5->DeviceNotSelectedTimeout = get_dword_from_reg( hkeyPrinter, dnsTimeoutW ); -- 1.9.1 From hverbeet at codeweavers.com Thu Oct 6 05:03:46 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Thu, 6 Oct 2016 12:03:46 +0200 Subject: [PATCH 1/7] wined3d: Store pointer to device in wined3d_context. In-Reply-To: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> References: <1475659029-16333-1-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Thu Oct 6 05:03:47 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Thu, 6 Oct 2016 12:03:47 +0200 Subject: [PATCH 2/7] wined3d: Avoid using "context->swapchain" in context_update_window(). In-Reply-To: <1475659029-16333-2-git-send-email-jkucia@codeweavers.com> References: <1475659029-16333-2-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Thu Oct 6 05:03:50 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Thu, 6 Oct 2016 12:03:50 +0200 Subject: [PATCH 5/7] wined3d: Avoid destroying active contexts. In-Reply-To: <1475659029-16333-5-git-send-email-jkucia@codeweavers.com> References: <1475659029-16333-5-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Thu Oct 6 05:03:48 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Thu, 6 Oct 2016 12:03:48 +0200 Subject: [PATCH 3/7] wined3d: Avoid trying to get backup DC when context is no longer associated with swapchain. In-Reply-To: <1475659029-16333-3-git-send-email-jkucia@codeweavers.com> References: <1475659029-16333-3-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Thu Oct 6 05:03:49 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Thu, 6 Oct 2016 12:03:49 +0200 Subject: [PATCH 4/7] wined3d: Call context_destroy() directly if context is not associated with swapchain. In-Reply-To: <1475659029-16333-4-git-send-email-jkucia@codeweavers.com> References: <1475659029-16333-4-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Thu Oct 6 05:03:51 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Thu, 6 Oct 2016 12:03:51 +0200 Subject: [PATCH resend 6/7] wined3d: Pass context to destroy_default_samplers(). In-Reply-To: <1475659029-16333-6-git-send-email-jkucia@codeweavers.com> References: <1475659029-16333-6-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Thu Oct 6 05:03:52 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Thu, 6 Oct 2016 12:03:52 +0200 Subject: [PATCH resend 7/7] wined3d: Pass context to destroy_dummy_textures(). In-Reply-To: <1475659029-16333-7-git-send-email-jkucia@codeweavers.com> References: <1475659029-16333-7-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From jacek at codeweavers.com Thu Oct 6 07:05:32 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Thu, 6 Oct 2016 14:05:32 +0200 Subject: winhttp: Added WINHTTP_OPTION_CLIENT_CERT_CONTEXT option stub. Message-ID: <153d0232-0c5e-6c1a-fd53-d89d06975e83@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/winhttp/session.c | 10 +++++++++- dlls/winhttp/tests/winhttp.c | 6 ++++++ include/winhttp.h | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-winhttp-Added-WINHTTP_OPTION_CLIENT_CERT_CONTEXT-opti.diff Type: text/x-patch Size: 2846 bytes Desc: not available URL: From aric at codeweavers.com Thu Oct 6 07:11:58 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 6 Oct 2016 07:11:58 -0500 Subject: [PATCH v2] winebus.sys: Implement IOCTL_HID_GET_DEVICE_ATTRIBUTES for hid devices Message-ID: <8c78f3fd-585c-6d33-666a-5e76cac2183b@codeweavers.com> v2: Suggestions from Sebastian Lackner Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_udev.c | 1 + dlls/winebus.sys/main.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: v2-0001-winebus.sys-Implement-IOCTL_HID_GET_DEVICE_ATTRIBUT.txt Type: text/x-patch Size: 3409 bytes Desc: not available URL: From aric at codeweavers.com Thu Oct 6 07:19:27 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 6 Oct 2016 07:19:27 -0500 Subject: [PATCH v3] winebus.sys: Implement IOCTL_HID_GET_DEVICE_ATTRIBUTES for hid devices Message-ID: <8494d8dc-3042-7e5a-554a-59449daf36b6@codeweavers.com> v2: Suggestions from Sebastian Lackner v3: Replaced a required missing IoCompleteRequest Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_udev.c | 1 + dlls/winebus.sys/main.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: v3-0001-winebus.sys-Implement-IOCTL_HID_GET_DEVICE_ATTRIBUT.txt Type: text/x-patch Size: 3457 bytes Desc: not available URL: From hans at codeweavers.com Thu Oct 6 07:37:05 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Thu, 06 Oct 2016 14:37:05 +0200 Subject: winhttp: Added WINHTTP_OPTION_CLIENT_CERT_CONTEXT option stub. In-Reply-To: <153d0232-0c5e-6c1a-fd53-d89d06975e83@codeweavers.com> References: <153d0232-0c5e-6c1a-fd53-d89d06975e83@codeweavers.com> Message-ID: <1475757425.6573.233.camel@codeweavers.com> Signed-off-by: Hans Leidekker From nsivov at codeweavers.com Thu Oct 6 07:49:52 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Thu, 6 Oct 2016 15:49:52 +0300 Subject: [v2 PATCH] d2d1/tests: Initial tests for bitmap render target Message-ID: <20161006124952.31244-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- v2: used compare_float(), used different vertical/horizontal dpi settings dlls/d2d1/tests/d2d1.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index c9e1692..ba4be0c 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -17,6 +17,7 @@ */ #define COBJMACROS +#include #include #include "d2d1.h" #include "wincrypt.h" @@ -76,6 +77,12 @@ static void set_size_u(D2D1_SIZE_U *size, unsigned int w, unsigned int h) size->height = h; } +static void set_size_f(D2D1_SIZE_F *size, float w, float h) +{ + size->width = w; + size->height = h; +} + static void set_matrix_identity(D2D1_MATRIX_3X2_F *matrix) { matrix->_11 = 1.0f; @@ -115,6 +122,22 @@ static void translate_matrix(D2D1_MATRIX_3X2_F *matrix, float x, float y) matrix->_32 += x * matrix->_12 + y * matrix->_22; } +static BOOL compare_float(float f, float g, unsigned int ulps) +{ + int x = *(int *)&f; + int y = *(int *)&g; + + if (x < 0) + x = INT_MIN - x; + if (y < 0) + y = INT_MIN - y; + + if (abs(x - y) > ulps) + return FALSE; + + return TRUE; +} + static BOOL compare_sha1(void *data, unsigned int pitch, unsigned int bpp, unsigned int w, unsigned int h, const char *ref_sha1) { @@ -2881,6 +2904,157 @@ static void test_hwnd_target(void) ID2D1Factory_Release(factory); } +static void test_bitmap_target(void) +{ + D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc; + D2D1_SIZE_U pixel_size, pixel_size2; + D2D1_RENDER_TARGET_PROPERTIES desc; + ID2D1HwndRenderTarget *hwnd_rt; + ID2D1Bitmap *bitmap, *bitmap2; + ID2D1BitmapRenderTarget *rt; + D2D1_SIZE_F size, size2; + ID2D1Factory *factory; + ID3D10Device1 *device; + float dpi[2], dpi2[2]; + D2D1_COLOR_F color; + ULONG refcount; + HRESULT hr; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + ID3D10Device1_Release(device); + + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); + ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr); + + desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + desc.dpiX = 96.0f; + desc.dpiY = 192.0f; + desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0); + ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n"); + hwnd_rt_desc.pixelSize.width = 64; + hwnd_rt_desc.pixelSize.height = 64; + hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE; + + hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &hwnd_rt); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt); +todo_wine + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + if (FAILED(hr)) + { + ID2D1HwndRenderTarget_Release(hwnd_rt); + DestroyWindow(hwnd_rt_desc.hwnd); + ID2D1Factory_Release(factory); + return; + } + + /* See if parent target is referenced. */ + ID2D1HwndRenderTarget_AddRef(hwnd_rt); + refcount = ID2D1HwndRenderTarget_Release(hwnd_rt); + ok(refcount == 1, "Target should not have been referenced, got %u.\n", refcount); + + /* Size was not specified, should match parent. */ + pixel_size = ID2D1HwndRenderTarget_GetPixelSize(hwnd_rt); + pixel_size2 = ID2D1BitmapRenderTarget_GetPixelSize(rt); + ok(!memcmp(&pixel_size, &pixel_size2, sizeof(pixel_size)), "Got target pixel size mismatch.\n"); + + size = ID2D1HwndRenderTarget_GetSize(hwnd_rt); + size2 = ID2D1BitmapRenderTarget_GetSize(rt); + ok(!memcmp(&size, &size2, sizeof(size)), "Got target DIP size mismatch.\n"); + + ID2D1HwndRenderTarget_GetDpi(hwnd_rt, dpi, dpi + 1); + ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1); + ok(!memcmp(dpi, dpi2, sizeof(dpi)), "Got dpi mismatch.\n"); + + ID2D1BitmapRenderTarget_Release(rt); + + /* Pixel size specified. */ + set_size_u(&pixel_size, 32, 32); + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, &pixel_size, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + pixel_size2 = ID2D1BitmapRenderTarget_GetPixelSize(rt); + ok(!memcmp(&pixel_size, &pixel_size2, sizeof(pixel_size)), "Got target pixel size mismatch.\n"); + + ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1); + ok(!memcmp(dpi, dpi2, sizeof(dpi)), "Got dpi mismatch.\n"); + + ID2D1BitmapRenderTarget_Release(rt); + + /* Both pixel size and DIP size are specified. */ + set_size_u(&pixel_size, 128, 128); + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, &size, &pixel_size, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + /* Doubled pixel size dimensions with the same DIP size give doubled dpi. */ + ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1); + ok(dpi[0] == dpi2[0] / 2.0f && dpi[1] == dpi2[1] / 2.0f, "Got dpi mismatch.\n"); + + ID2D1BitmapRenderTarget_Release(rt); + + /* DIP size is specified, fractional. */ + set_size_f(&size, 70.1f, 70.4f); + hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, &size, NULL, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1); + + pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(rt); + ok(pixel_size.width == ceilf(size.width * dpi2[0] / 96.0f) + && pixel_size.height == ceilf(size.height * dpi2[1] / 96.0f), "Wrong pixel size %ux%u\n", + pixel_size.width, pixel_size.height); + + dpi[0] *= (pixel_size.width / size.width) * (96.0f / dpi[0]); + dpi[1] *= (pixel_size.height / size.height) * (96.0f / dpi[1]); + + ok(compare_float(dpi[0], dpi2[0], 1) && compare_float(dpi[1], dpi2[1], 1), "Got dpi mismatch.\n"); + + ID2D1HwndRenderTarget_Release(hwnd_rt); + + /* Check if GetBitmap() returns same instance. */ + hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap); + ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr); + hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap2); + ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr); + ok(bitmap == bitmap2, "Got different bitmap instances.\n"); + + /* Draw something, see if bitmap instance is retained. */ + ID2D1BitmapRenderTarget_BeginDraw(rt); + set_color(&color, 1.0f, 1.0f, 0.0f, 1.0f); + ID2D1BitmapRenderTarget_Clear(rt, &color); + hr = ID2D1BitmapRenderTarget_EndDraw(rt, NULL, NULL); + ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr); + + ID2D1Bitmap_Release(bitmap2); + hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap2); + ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr); + ok(bitmap == bitmap2, "Got different bitmap instances.\n"); + + ID2D1Bitmap_Release(bitmap); + ID2D1Bitmap_Release(bitmap2); + + refcount = ID2D1BitmapRenderTarget_Release(rt); + ok(!refcount, "Target should be released, got %u.\n", refcount); + + DestroyWindow(hwnd_rt_desc.hwnd); + ID2D1Factory_Release(factory); +} + START_TEST(d2d1) { test_clip(); @@ -2897,4 +3071,5 @@ START_TEST(d2d1) test_draw_text_layout(); test_dc_target(); test_hwnd_target(); + test_bitmap_target(); } -- 2.9.3 From piotr at codeweavers.com Thu Oct 6 08:04:23 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Thu, 6 Oct 2016 15:04:23 +0200 Subject: [PATCH] msvcrt: Implement 64-bit version of __std_type_info_hash (try 2) In-Reply-To: <1475693512-10507-1-git-send-email-ale.goujon@gmail.com> References: <1475693512-10507-1-git-send-email-ale.goujon@gmail.com> Message-ID: <41b5512f-ab62-2e93-face-c94c406e2d2e@codeweavers.com> I'm not sure if the From and Sign-Off fields are correct. Other then that it looks OK for me. Signed-off-by: Piotr Caban From jacek at codeweavers.com Thu Oct 6 08:01:40 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Thu, 6 Oct 2016 15:01:40 +0200 Subject: [PATCH 02/16 v2] rpcrt4: Use NtReadFile in rpcrt4_conn_np_read. Message-ID: Signed-off-by: Jacek Caban --- dlls/rpcrt4/rpc_transport.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-rpcrt4-Use-NtReadFile-in-rpcrt4_conn_np_read.diff Type: text/x-patch Size: 1371 bytes Desc: not available URL: From andrey.goosev at gmail.com Thu Oct 6 08:31:50 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Thu, 6 Oct 2016 16:31:50 +0300 Subject: wined3d: Add missing '\n' to FIXME() messages. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: wined3d-Add-missing-n-to-FIXME-messages.patch Type: text/x-patch Size: 1466 bytes Desc: not available URL: From sebastian at fds-team.de Thu Oct 6 08:54:21 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Thu, 6 Oct 2016 15:54:21 +0200 Subject: [PATCH v3] winebus.sys: Implement IOCTL_HID_GET_DEVICE_ATTRIBUTES for hid devices In-Reply-To: <8494d8dc-3042-7e5a-554a-59449daf36b6@codeweavers.com> References: <8494d8dc-3042-7e5a-554a-59449daf36b6@codeweavers.com> Message-ID: 2016-10-06 14:19 GMT+02:00 Aric Stewart : > > v2: Suggestions from Sebastian Lackner > v3: Replaced a required missing IoCompleteRequest > Signed-off-by: Aric Stewart > --- > dlls/winebus.sys/bus.h | 1 + > dlls/winebus.sys/bus_udev.c | 1 + > dlls/winebus.sys/main.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 48 insertions(+) > Signed-off-by: Sebastian Lackner From jacek at codeweavers.com Thu Oct 6 10:04:02 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Thu, 6 Oct 2016 17:04:02 +0200 Subject: mshtml: Fixed leak in get_nsstyle_attr_nsval. Message-ID: <153eab84-54e1-424e-6206-4aae4a49b3c8@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/mshtml/htmlstyle.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-mshtml-Fixed-leak-in-get_nsstyle_attr_nsval.diff Type: text/x-patch Size: 630 bytes Desc: not available URL: From mbruni at codeweavers.com Thu Oct 6 17:57:49 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Fri, 7 Oct 2016 00:57:49 +0200 Subject: [PATCH 1/5] wined3d: Slightly offset the viewport in the ARB_clip_control case. Message-ID: <1475794673-28114-1-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- Match the preexisting behavior of the non-ARB_clip_control codepath, mostly for the top-left filling convention point mentioned in get_projection_matrix(). dlls/wined3d/directx.c | 2 +- dlls/wined3d/state.c | 4 +++- dlls/wined3d/utils.c | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 5d91981..98b05c1 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -3862,7 +3862,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD gl_info->gl_ops.gl.p_glGetIntegerv(GL_VIEWPORT_SUBPIXEL_BITS, &subpixel_bits); TRACE("Viewport supports %d subpixel bits.\n", subpixel_bits); - if (!subpixel_bits) + if (subpixel_bits < 8) gl_info->supported[ARB_VIEWPORT_ARRAY] = FALSE; } if (gl_info->supported[ARB_CLIP_CONTROL] && !gl_info->supported[ARB_VIEWPORT_ARRAY]) diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 0333dd4..71f47d6 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -4653,8 +4653,10 @@ static void viewport_miscpart_cc(struct wined3d_context *context, { const struct wined3d_rendertarget_view *depth_stencil = state->fb->depth_stencil; const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; + /* See get_projection_matrix() in utils.c for a discussion about those + * values. */ float pixel_center_offset = context->device->wined3d->flags - & WINED3D_PIXEL_CENTER_INTEGER ? 0.5f : 0.0f; + & WINED3D_PIXEL_CENTER_INTEGER ? 63.0f / 128.0f : -1.0f / 128.0f; const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_viewport vp = state->viewport; unsigned int width, height; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index e65907a..8e83040 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -4502,8 +4502,8 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w * here besides the projection transformation itself: * - We need to flip along the y-axis in case of offscreen rendering. * - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}. - * - D3D coordinates refer to pixel centers while GL coordinates refer - * to pixel corners. + * - <= D3D9 coordinates refer to pixel centers while GL coordinates + * refer to pixel corners. * - D3D has a top-left filling convention. We need to maintain this * even after the y-flip mentioned above. * In order to handle the last two points, we translate by -- 2.7.3 From mbruni at codeweavers.com Thu Oct 6 17:57:50 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Fri, 7 Oct 2016 00:57:50 +0200 Subject: [PATCH 2/5] wined3d: Account for offscreen rendering in the pixel shader key only if vpos is used. In-Reply-To: <1475794673-28114-1-git-send-email-mbruni@codeweavers.com> References: <1475794673-28114-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1475794673-28114-2-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- dlls/wined3d/shader.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 594520c..4455416 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -3280,7 +3280,8 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 if (d3d_info->emulated_flatshading) args->flatshading = state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT; - args->render_offscreen = gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS] ? context->render_offscreen : 0; + args->render_offscreen = shader->reg_maps.vpos && gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS] + ? context->render_offscreen : 0; } static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, -- 2.7.3 From mbruni at codeweavers.com Thu Oct 6 17:57:51 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Fri, 7 Oct 2016 00:57:51 +0200 Subject: [PATCH 3/5] wined3d: Flag WINED3D_SHADER_CONST_PS_Y_CORR on framebuffer changes. In-Reply-To: <1475794673-28114-1-git-send-email-mbruni@codeweavers.com> References: <1475794673-28114-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1475794673-28114-3-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- dlls/wined3d/context.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 394a2dc..98516f8 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -2758,6 +2758,7 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat context_apply_draw_buffers(context, rt_mask); *cur_mask = rt_mask; } + context->constant_update_mask |= WINED3D_SHADER_CONST_PS_Y_CORR; } static void context_map_stage(struct wined3d_context *context, DWORD stage, DWORD unit) -- 2.7.3 From mbruni at codeweavers.com Thu Oct 6 17:57:52 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Fri, 7 Oct 2016 00:57:52 +0200 Subject: [PATCH 4/5] d3d9/tests: Make the window client rect match the d3d swapchain size. In-Reply-To: <1475794673-28114-1-git-send-email-mbruni@codeweavers.com> References: <1475794673-28114-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1475794673-28114-4-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- So that we don't end up enabling render_to_fbo in the AlwaysOffscreen disabled case (thus essentially falling back to offscreen rendering). dlls/d3d9/tests/visual.c | 303 ++++++++++++++++------------------------------- 1 file changed, 103 insertions(+), 200 deletions(-) diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index b55c1f2..162620f 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -51,16 +51,14 @@ struct vec4 static HWND create_window(void) { - WNDCLASSA wc = {0}; - HWND ret; - wc.lpfnWndProc = DefWindowProcA; - wc.lpszClassName = "d3d9_test_wc"; - RegisterClassA(&wc); - - ret = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_SYSMENU | WS_POPUP, - 0, 0, 640, 480, 0, 0, 0, 0); - ShowWindow(ret, SW_SHOW); - return ret; + HWND hwnd; + RECT rect; + + SetRect(&rect, 0, 0, 640, 480); + AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE); + hwnd = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 0, 0, rect.right - rect.left, rect.bottom - rect.top, 0, 0, 0, 0); + return hwnd; } static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff) @@ -256,8 +254,7 @@ static void test_sanity(void) HWND window; HRESULT hr; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -414,8 +411,7 @@ static void lighting_test(void) {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -790,8 +786,7 @@ static void test_specular_lighting(void) } } - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -907,8 +902,7 @@ static void clear_test(void) ULONG refcount; HWND window; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -1346,8 +1340,7 @@ static void color_fill_test(void) DWORD *surface_data; static const RECT rect = {4, 4, 8, 8}, rect2 = {5, 5, 7, 7}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -1581,8 +1574,7 @@ static void test_mova(void) D3DDECL_END() }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -1795,8 +1787,7 @@ static void fog_test(void) 12, 13, 14, 14, 15, 12, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -2242,8 +2233,7 @@ static void test_cube_wrap(void) {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -2404,8 +2394,7 @@ static void offscreen_test(void) { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -2791,8 +2780,7 @@ static void fog_with_shader_test(void) 0.0f, 0.0f, 0.0f, 1.0f, }}}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -3051,8 +3039,7 @@ static void texbem_test(void) }, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -3349,8 +3336,7 @@ static void z_range_test(void) static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f}; static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -3583,8 +3569,7 @@ static void stretchrect_test(void) static const RECT dst_rect64 = {0, 0, 64, 64}; static const RECT dst_rect64_flipy = {0, 64, 64, 0}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -4106,8 +4091,7 @@ static void maxmip_test(void) }}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -4339,8 +4323,7 @@ static void release_buffer_test(void) {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -4430,8 +4413,7 @@ static void float_texture_test(void) 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -4510,8 +4492,7 @@ static void g16r16_texture_test(void) 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -4797,8 +4778,7 @@ static void texture_transform_flags_test(void) 0.0f, 0.0f, 0.0f, 1.0f, }}}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -5487,8 +5467,7 @@ static void texdepth_test(void) 1.0f, 1.0f, 1.0f, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -5712,8 +5691,7 @@ static void texkill_test(void) 0x0000ffff /* end */ }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -5880,8 +5858,7 @@ static void autogen_mipmap_test(void) 0.5f, 0.5f, 0.1f, 1.0f, 1.0f, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -6067,8 +6044,7 @@ static void test_constant_clamp_vs(void) static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f}; static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -6248,8 +6224,7 @@ static void constant_clamp_ps_test(void) static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f}; static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -6398,8 +6373,7 @@ static void dp2add_ps_test(void) 1.0f, 1.0f, 0.1f, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -6686,8 +6660,7 @@ static void cnd_test(void) static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f}; static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -7056,8 +7029,7 @@ static void nested_loop_test(void) 1.0f, 1.0f, 0.1f, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -7323,8 +7295,7 @@ static void pretransformed_varying_test(void) HRESULT hr; BOOL warp; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -7486,8 +7457,7 @@ static void test_compare_instructions(void) static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f}; static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -7834,8 +7804,7 @@ static void test_vshader_input(void) static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f}; static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -8169,8 +8138,7 @@ static void srgbtexture_test(void) 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -8354,8 +8322,7 @@ static void test_shademode(void) {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -8531,8 +8498,7 @@ static void test_blend(void) { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -8811,8 +8777,7 @@ static void fixed_function_decl_test(void) {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -9352,8 +9317,7 @@ static void test_vshader_float16(void) { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 }, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -9482,8 +9446,7 @@ static void conditional_np2_repeat_test(void) 1.0f, 1.0f, 0.1f, 1.2f, 1.2f, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -9664,8 +9627,7 @@ static void vface_register_test(void) 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -9795,8 +9757,7 @@ static void fixed_function_bumpmap_test(void) /* use asymmetric matrix to test loading */ static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -10071,8 +10032,7 @@ static void stencil_cull_test(void) unsigned int i; DWORD color; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -10286,8 +10246,7 @@ static void test_fragment_coords(void) }; float constant[4] = {1.0, 0.0, 320, 240}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -10657,8 +10616,7 @@ static void test_pointsize(void) -1.0f, 1.0f, 0.0f, 1.0f, }}}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -11078,8 +11036,7 @@ static void multiple_rendertargets_test(void) 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -11305,8 +11262,7 @@ static void pixelshader_blending_test(void) {{ 1.0f, 1.0f, 0.1f}, 0x80201000}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -11471,8 +11427,7 @@ static void tssargtemp_test(void) {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -11640,8 +11595,7 @@ static void stream_test(void) D3DDECL_END() }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -11867,8 +11821,7 @@ static void np2_stretch_rect_test(void) 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -12025,8 +11978,7 @@ static void texop_test(void) {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -12173,8 +12125,7 @@ static void yuv_color_test(void) {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -12310,8 +12261,7 @@ static void yuv_layout_test(void) { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", }, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -12476,8 +12426,7 @@ static void texop_range_test(void) { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)} }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -12610,8 +12559,7 @@ static void alphareplicate_test(void) {{ 1.0f, 1.0f, 0.1f}, 0x80ff00ff}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -12674,8 +12622,7 @@ static void dp3_alpha_test(void) {{ 1.0f, 1.0f, 0.1f}, 0x408080c0}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -12778,8 +12725,7 @@ static void zwriteenable_test(void) {{ 1.0f, 1.0f, 0.9f}, 0x0000ff00}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -12880,8 +12826,7 @@ static void alphatest_test(void) {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -13030,8 +12975,7 @@ static void sincos_test(void) static const float sincosc1[4] = {D3DSINCOSCONST1}; static const float sincosc2[4] = {D3DSINCOSCONST2}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -13134,8 +13078,7 @@ static void loop_index_test(void) static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f}; static const int i0[4] = {2, 10, -3, 0}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -13256,8 +13199,7 @@ static void sgn_test(void) 1.0f, 1.0f, 0.1f, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -13323,8 +13265,7 @@ static void viewport_test(void) 0.5f, 0.5f, 0.1f, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -13479,8 +13420,7 @@ static void depth_clamp_test(void) {{ 1.0f, 0.25f, 10.0f}, 0xfff91414}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -13641,8 +13581,7 @@ static void depth_bounds_test(void) HWND window; HRESULT hr; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, @@ -13781,8 +13720,7 @@ static void depth_buffer_test(void) HWND window; HRESULT hr; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -13917,8 +13855,7 @@ static void depth_buffer2_test(void) HWND window; HRESULT hr; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -14050,8 +13987,7 @@ static void depth_blit_test(void) HWND window; HRESULT hr; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -14241,8 +14177,7 @@ static void intz_test(void) HRESULT hr; UINT i; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, @@ -14562,8 +14497,7 @@ static void shadow_test(void) HRESULT hr; UINT i; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -14783,8 +14717,7 @@ static void clip_planes_test(void) 0x0000ffff /* end */ }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -15001,8 +14934,7 @@ static void fp_special_test(void) HRESULT hr; UINT i; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -15130,8 +15062,7 @@ static void srgbwrite_format_test(void) { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f} }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -15251,8 +15182,7 @@ static void ds_size_test(void) { 1.0f, 1.0f, 0.0f}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -15400,8 +15330,7 @@ static void unbound_sampler_test(void) { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f} }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -15568,8 +15497,7 @@ static void update_surface_test(void) HWND window; HRESULT hr; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, @@ -15705,8 +15633,7 @@ static void multisample_get_rtdata_test(void) HWND window; HRESULT hr; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, @@ -16578,8 +16505,7 @@ static void zenable_test(void) UINT test; IDirect3DSurface9 *ds; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -16813,8 +16739,7 @@ static void fog_special_test(void) D3DCAPS9 caps; HWND window; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -16974,8 +16899,7 @@ static void volume_srgb_test(void) {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, @@ -17101,8 +17025,7 @@ static void volume_dxt5_test(void) }; static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, @@ -17210,8 +17133,7 @@ static void volume_v16u16_test(void) 0x0000ffff /* end */ }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -17373,8 +17295,7 @@ static void add_dirty_rect_test(void) static const RECT part_rect = {96, 96, 160, 160}; DWORD color; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -17701,8 +17622,7 @@ static void test_per_stage_constant(void) {{ 1.0f, 1.0f, 0.1f}, 0xffff0000}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -17877,8 +17797,7 @@ static void test_3dc_formats(void) HRESULT hr; unsigned int i; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, @@ -18036,8 +17955,7 @@ static void test_fog_interpolation(void) }}}; D3DCAPS9 caps; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); @@ -18211,8 +18129,7 @@ static void test_negative_fixedfunction_fog(void) }; D3DCAPS9 caps; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); @@ -18376,8 +18293,7 @@ static void test_position_index(void) HRESULT hr; unsigned int i; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -18540,8 +18456,7 @@ static void test_table_fog_zw(void) }; unsigned int i; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); @@ -18798,8 +18713,7 @@ static void test_signed_formats(void) }; D3DCOLOR expected_color; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); @@ -19018,8 +18932,7 @@ static void test_multisample_mismatch(void) {{ 1.0f, 1.0f, 1.0f}, 0x000000ff}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, @@ -19246,8 +19159,7 @@ static void test_texcoordindex(void) D3DCOLOR color; DWORD *ptr; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d9 = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d9, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d9, window, window, TRUE))) @@ -19550,8 +19462,7 @@ static void test_vertex_blending(void) }, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -19757,8 +19668,7 @@ static void test_updatetexture(void) quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"} }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d9 = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d9, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d9, window, window, TRUE))) @@ -20031,8 +19941,7 @@ static void test_depthbias(void) DWORD d; } conv; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -20171,8 +20080,7 @@ static void test_flip(void) D3DCOLOR color; D3DPRESENT_PARAMETERS present_parameters = {0}; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); @@ -20501,8 +20409,7 @@ static void test_uninitialized_varyings(void) D3DCOLOR color; BOOL warp; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -20624,8 +20531,7 @@ static void test_multisample_init(void) struct surface_readback rb; BOOL all_zero = TRUE; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); @@ -21360,8 +21266,7 @@ static void test_texture_blending(void) }, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d, window, window, TRUE))) @@ -21610,8 +21515,7 @@ static void test_color_clamping(void) HWND window; HRESULT hr; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d9 = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d9, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d9, window, window, TRUE))) @@ -21767,8 +21671,7 @@ static void test_line_antialiasing_blending(void) {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)}, }; - window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + window = create_window(); d3d9 = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d9, "Failed to create a D3D object.\n"); if (!(device = create_device(d3d9, window, window, TRUE))) -- 2.7.3 From mbruni at codeweavers.com Thu Oct 6 17:57:53 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Fri, 7 Oct 2016 00:57:53 +0200 Subject: [PATCH 5/5] d3d9/tests: Add a test for the dsy SM3 instruction. In-Reply-To: <1475794673-28114-1-git-send-email-mbruni@codeweavers.com> References: <1475794673-28114-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1475794673-28114-5-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- dlls/d3d9/tests/visual.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index 162620f..20e3eb9 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -21804,6 +21804,133 @@ static void test_line_antialiasing_blending(void) DestroyWindow(window); } +static void test_dsy(void) +{ + static const DWORD vs_code[] = + { + 0xfffe0300, /* vs_3_0 */ + 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */ + 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */ + 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */ + 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */ + 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */ + 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */ + 0x0000ffff + }; + static const DWORD ps_code[] = + { + 0xffff0300, /* ps_3_0 */ + 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */ + 0x05000051, 0xa00f0000, 0x43700000, 0x3f000000, 0x00000000, 0x00000000, /* def c0, 240.0, 0.5, 0.0, 0.0 */ + 0x0200005c, 0x800f0000, 0x90e40000, /* dsy r0, v0 */ + 0x03000005, 0x800f0000, 0x80e40000, 0xa0000000, /* mul r0, r0, c0.x */ + 0x03000002, 0x800f0800, 0x80e40000, 0xa0550000, /* add oC0, r0, c0.y */ + 0x0000ffff + }; + static const struct + { + struct vec3 pos; + D3DCOLOR color; + } + quad[] = + { + {{-1.0f, -1.0f, 0.1f}, 0x00ff0000}, + {{-1.0f, 1.0f, 0.1f}, 0x0000ff00}, + {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000}, + {{ 1.0f, 1.0f, 0.1f}, 0x0000ff00}, + }; + IDirect3DSurface9 *backbuffer, *rt; + IDirect3DVertexShader9 *vs; + IDirect3DPixelShader9 *ps; + IDirect3DDevice9 *device; + IDirect3D9 *d3d; + ULONG refcount; + D3DCAPS9 caps; + DWORD color; + HWND window; + HRESULT hr; + + window = create_window(); + d3d = Direct3DCreate9(D3D_SDK_VERSION); + ok(!!d3d, "Failed to create a D3D object.\n"); + if (!(device = create_device(d3d, window, window, TRUE))) + { + skip("Failed to create a D3D device, skipping tests.\n"); + goto done; + } + + hr = IDirect3DDevice9_GetDeviceCaps(device, &caps); + ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr); + if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0)) + { + skip("No ps_3_0 support, skipping dsy tests.\n"); + IDirect3DDevice9_Release(device); + goto done; + } + + hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); + ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr); + + hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8, + D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL); + ok(SUCCEEDED(hr), "Failed to create offscreen render target, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt); + ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr); + + hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs); + ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); + hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps); + ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr); + + hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE); + ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetVertexShader(device, vs); + ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetPixelShader(device, ps); + ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr); + + hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0); + ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr); + hr = IDirect3DDevice9_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad)); + ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr); + hr = IDirect3DDevice9_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + + color = getPixelColor(device, 360, 240); + ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color); + + hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer); + ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr); + + hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0); + ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr); + hr = IDirect3DDevice9_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0])); + ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr); + hr = IDirect3DDevice9_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + + color = getPixelColor(device, 360, 240); + ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color); + + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr); + + IDirect3DSurface9_Release(rt); + IDirect3DSurface9_Release(backbuffer); + IDirect3DVertexShader9_Release(vs); + IDirect3DPixelShader9_Release(ps); + + refcount = IDirect3DDevice9_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +done: + IDirect3D9_Release(d3d); + DestroyWindow(window); +} + START_TEST(visual) { D3DADAPTER_IDENTIFIER9 identifier; @@ -21928,4 +22055,5 @@ START_TEST(visual) test_texture_blending(); test_color_clamping(); test_line_antialiasing_blending(); + test_dsy(); } -- 2.7.3 From sebastian at fds-team.de Thu Oct 6 22:13:59 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Fri, 7 Oct 2016 05:13:59 +0200 Subject: [1/3] ntoskrnl.exe: Fix a copy & paste error in dispatch_close. Message-ID: Signed-off-by: Sebastian Lackner --- Those options do not make any sense for IRP_MJ_CLOSE (and also would have to be stored in params->close instead of params->create). dlls/ntoskrnl.exe/ntoskrnl.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index cc6ea0b..258f76d 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -259,11 +259,6 @@ static NTSTATUS dispatch_close( const irp_params_t *params, void *in_buff, ULONG irpsp->MajorFunction = IRP_MJ_CLOSE; irpsp->DeviceObject = device; irpsp->CompletionRoutine = NULL; - irpsp->Parameters.Create.SecurityContext = NULL; /* FIXME */ - irpsp->Parameters.Create.Options = params->create.options; - irpsp->Parameters.Create.ShareAccess = params->create.sharing; - irpsp->Parameters.Create.FileAttributes = 0; - irpsp->Parameters.Create.EaLength = 0; irp->Tail.Overlay.OriginalFileObject = file; irp->RequestorMode = UserMode; -- 2.9.0 From sebastian at fds-team.de Thu Oct 6 22:19:46 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Fri, 7 Oct 2016 05:19:46 +0200 Subject: [2/3] ntoskrnl.exe: Remove checks if MajorFunction is NULL. Message-ID: Signed-off-by: Sebastian Lackner --- Now that all MajorFunction pointers are always initialized, this is unnecessary. The returned status code also matches the behavior on Windows: http://newtestbot.winehq.org/JobDetails.pl?Key=26063 http://newtestbot.winehq.org/JobDetails.pl?Key=26065 I've also modified dispatch_irp() to a void function because it cannot really fail. In order to fix a bunch of invalid memory accesses, I am planning to send some follow-up patches which return different values from dispatch_*() functions depending on if they still needs the input buffer. Notes: * For dispatch_create / dispatch_close the exact status does not matter (yet) because it is never really checked in wineserver. * For dispatch_flush the ntdll code has no way to access the status yet, so it will return STATUS_SUCCESS even if IRP_MJ_FLUSH_BUFFERS is unimplemented. dlls/ntoskrnl.exe/ntoskrnl.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 258f76d..d107bd9 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -172,7 +172,7 @@ static HANDLE get_device_manager(void) return ret; } -static NTSTATUS dispatch_irp( DEVICE_OBJECT *device, IRP *irp ) +static void dispatch_irp( DEVICE_OBJECT *device, IRP *irp ) { LARGE_INTEGER count; @@ -183,8 +183,6 @@ static NTSTATUS dispatch_irp( DEVICE_OBJECT *device, IRP *irp ) IoCallDriver( device, irp ); device->CurrentIrp = NULL; - - return STATUS_SUCCESS; } /* process a create request for a given file */ @@ -227,10 +225,8 @@ static NTSTATUS dispatch_create( const irp_params_t *params, void *in_buff, ULON irp->UserIosb = irp_handle; /* note: we abuse UserIosb to store the server irp handle */ irp->UserEvent = NULL; - if (device->DriverObject->MajorFunction[IRP_MJ_CREATE]) return dispatch_irp( device, irp ); + dispatch_irp( device, irp ); - irp->IoStatus.u.Status = STATUS_SUCCESS; - IoCompleteRequest( irp, IO_NO_INCREMENT ); return STATUS_SUCCESS; } @@ -267,12 +263,7 @@ static NTSTATUS dispatch_close( const irp_params_t *params, void *in_buff, ULONG irp->UserIosb = irp_handle; /* note: we abuse UserIosb to store the server irp handle */ irp->UserEvent = NULL; - if (!device->DriverObject->MajorFunction[IRP_MJ_CLOSE]) - { - irp->IoStatus.u.Status = STATUS_SUCCESS; - IoCompleteRequest( irp, IO_NO_INCREMENT ); - } - else dispatch_irp( device, irp ); + dispatch_irp( device, irp ); HeapFree( GetProcessHeap(), 0, file ); /* FIXME: async close processing not supported */ return STATUS_SUCCESS; @@ -292,7 +283,6 @@ static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG if (!file) return STATUS_INVALID_HANDLE; device = file->DeviceObject; - if (!device->DriverObject->MajorFunction[IRP_MJ_READ]) return STATUS_NOT_SUPPORTED; TRACE( "device %p file %p size %u\n", device, file, out_size ); @@ -314,7 +304,9 @@ static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG irpsp = IoGetNextIrpStackLocation( irp ); irpsp->Parameters.Read.Key = params->read.key; - return dispatch_irp( device, irp ); + dispatch_irp( device, irp ); + + return STATUS_SUCCESS; } /* process a write request for a given device */ @@ -330,7 +322,6 @@ static NTSTATUS dispatch_write( const irp_params_t *params, void *in_buff, ULONG if (!file) return STATUS_INVALID_HANDLE; device = file->DeviceObject; - if (!device->DriverObject->MajorFunction[IRP_MJ_WRITE]) return STATUS_NOT_SUPPORTED; TRACE( "device %p file %p size %u\n", device, file, in_size ); @@ -347,7 +338,9 @@ static NTSTATUS dispatch_write( const irp_params_t *params, void *in_buff, ULONG irpsp = IoGetNextIrpStackLocation( irp ); irpsp->Parameters.Write.Key = params->write.key; - return dispatch_irp( device, irp ); + dispatch_irp( device, irp ); + + return STATUS_SUCCESS; } /* process a flush request for a given device */ @@ -361,7 +354,6 @@ static NTSTATUS dispatch_flush( const irp_params_t *params, void *in_buff, ULONG if (!file) return STATUS_INVALID_HANDLE; device = file->DeviceObject; - if (!device->DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS]) return STATUS_NOT_SUPPORTED; TRACE( "device %p file %p\n", device, file ); @@ -373,7 +365,9 @@ static NTSTATUS dispatch_flush( const irp_params_t *params, void *in_buff, ULONG irp->Tail.Overlay.OriginalFileObject = file; irp->RequestorMode = UserMode; - return dispatch_irp( device, irp ); + dispatch_irp( device, irp ); + + return STATUS_SUCCESS; } /* process an ioctl request for a given device */ @@ -388,7 +382,6 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG if (!file) return STATUS_INVALID_HANDLE; device = file->DeviceObject; - if (!device->DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]) return STATUS_NOT_SUPPORTED; TRACE( "ioctl %x device %p file %p in_size %u out_size %u\n", params->ioctl.code, device, file, in_size, out_size ); @@ -417,7 +410,9 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG irp->Tail.Overlay.OriginalFileObject = file; irp->RequestorMode = UserMode; - return dispatch_irp( device, irp ); + dispatch_irp( device, irp ); + + return STATUS_SUCCESS; } typedef NTSTATUS (*dispatch_func)( const irp_params_t *params, void *in_buff, ULONG in_size, -- 2.9.0 From sebastian at fds-team.de Thu Oct 6 22:20:01 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Fri, 7 Oct 2016 05:20:01 +0200 Subject: [3/3] ntoskrnl.exe: Fix parameters of IoBuildSynchronousFsdRequest in dispatch_flush. Message-ID: Signed-off-by: Sebastian Lackner --- IRP_MJ_FLUSH_BUFFERS does not expect any input buffer. MSDN also mentions for IoBuildSynchronousFsdRequest: """If MajorFunction is IRP_MJ_FLUSH_BUFFERS or IRP_MJ_SHUTDOWN, this parameter must be NULL.""" dlls/ntoskrnl.exe/ntoskrnl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index aac059e..ba2c328 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -358,7 +358,7 @@ static NTSTATUS dispatch_flush( const irp_params_t *params, void *in_buff, ULONG TRACE( "device %p file %p\n", device, file ); /* note: we abuse UserIosb to store the server irp handle */ - if (!(irp = IoBuildSynchronousFsdRequest( IRP_MJ_FLUSH_BUFFERS, device, in_buff, in_size, + if (!(irp = IoBuildSynchronousFsdRequest( IRP_MJ_FLUSH_BUFFERS, device, NULL, 0, NULL, NULL, irp_handle ))) return STATUS_NO_MEMORY; -- 2.9.0 From huw at codeweavers.com Fri Oct 7 04:49:30 2016 From: huw at codeweavers.com (Huw Davies) Date: Fri, 7 Oct 2016 10:49:30 +0100 Subject: [PATCH 1/8] riched20: Don't try to wrap the end-of-paragraph run. Message-ID: <1475833777-45995-1-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/wrap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index 24a7b16..4c73c5d 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -624,8 +624,8 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p) wc->pt.x + run->nWidth - wc->context->pt.x > wc->nAvailWidth) { int loc = wc->context->pt.x + wc->nAvailWidth - wc->pt.x; - /* total white run ? */ - if (run->nFlags & MERF_WHITESPACE) { + /* total white run or end para */ + if (run->nFlags & (MERF_WHITESPACE | MERF_ENDPARA)) { /* let the overflow logic handle it */ wc->bOverflown = TRUE; return p; -- 2.8.2 From huw at codeweavers.com Fri Oct 7 04:49:31 2016 From: huw at codeweavers.com (Huw Davies) Date: Fri, 7 Oct 2016 10:49:31 +0100 Subject: [PATCH 2/8] riched20: Reset the numbering style info after a \pard . Message-ID: <1475833777-45995-2-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/editor.c | 10 ++++++++-- dlls/riched20/tests/editor.c | 6 ++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index e2a44d3..da9425e 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -553,8 +553,9 @@ void ME_RTFParAttrHook(RTF_Info *info) info->borderType = RTFBorderParaTop; info->fmt.dwMask = PFM_ALIGNMENT | PFM_BORDER | PFM_LINESPACING | PFM_TABSTOPS | PFM_OFFSET | PFM_RIGHTINDENT | PFM_SPACEAFTER | PFM_SPACEBEFORE | - PFM_STARTINDENT | PFM_RTLPARA; - /* TODO: numbering, shading */ + PFM_STARTINDENT | PFM_RTLPARA | PFM_NUMBERING | PFM_NUMBERINGSTART | + PFM_NUMBERINGSTYLE | PFM_NUMBERINGTAB; + /* TODO: shading */ info->fmt.wAlignment = PFA_LEFT; info->fmt.cTabCount = 0; info->fmt.dxOffset = info->fmt.dxStartIndent = info->fmt.dxRightIndent = 0; @@ -564,6 +565,11 @@ void ME_RTFParAttrHook(RTF_Info *info) info->fmt.dySpaceBefore = info->fmt.dySpaceAfter = 0; info->fmt.dyLineSpacing = 0; info->fmt.wEffects &= ~PFE_RTLPARA; + info->fmt.wNumbering = 0; + info->fmt.wNumberingStart = 0; + info->fmt.wNumberingStyle = 0; + info->fmt.wNumberingTab = 0; + if (!info->editor->bEmulateVersion10) /* v4.1 */ { if (info->tableDef && info->tableDef->tableRowStart && diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 351695a..ad51e64 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -1307,6 +1307,12 @@ static void test_SETPARAFORMAT(void) ok(ret == expectedMask, "expected %x got %x\n", expectedMask, ret); ok(fmt.dwMask == expectedMask, "expected %x got %x\n", expectedMask, fmt.dwMask); + /* Test some other paraformat field defaults */ + ok( fmt.wNumbering == 0, "got %d\n", fmt.wNumbering ); + ok( fmt.wNumberingStart == 0, "got %d\n", fmt.wNumberingStart ); + ok( fmt.wNumberingStyle == 0, "got %04x\n", fmt.wNumberingStyle ); + ok( fmt.wNumberingTab == 0, "got %d\n", fmt.wNumberingTab ); + DestroyWindow(hwndRichEdit); } -- 2.8.2 From huw at codeweavers.com Fri Oct 7 04:49:32 2016 From: huw at codeweavers.com (Huw Davies) Date: Fri, 7 Oct 2016 10:49:32 +0100 Subject: [PATCH 3/8] riched20: Implement parsing of the paragraph numbering destination. Message-ID: <1475833777-45995-3-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/editor.c | 117 ++++++++++++++++++++++++++++++++++++++----- dlls/riched20/reader.c | 4 +- dlls/riched20/tests/editor.c | 69 +++++++++++++++++++++++++ 3 files changed, 176 insertions(+), 14 deletions(-) diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index da9425e..162daa8 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -763,18 +763,6 @@ void ME_RTFParAttrHook(RTF_Info *info) info->fmt.dwMask |= PFM_NUMBERING; info->fmt.wNumbering = 2; /* FIXME: MSDN says it's not used ?? */ break; - case rtfParNumDecimal: - info->fmt.dwMask |= PFM_NUMBERING; - info->fmt.wNumbering = 2; /* FIXME: MSDN says it's not used ?? */ - break; - case rtfParNumIndent: - info->fmt.dwMask |= PFM_NUMBERINGTAB; - info->fmt.wNumberingTab = info->rtfParam; - break; - case rtfParNumStartAt: - info->fmt.dwMask |= PFM_NUMBERINGSTART; - info->fmt.wNumberingStart = info->rtfParam; - break; case rtfBorderLeft: info->borderType = RTFBorderParaLeft; info->fmt.wBorders |= 1; @@ -1432,6 +1420,110 @@ static void ME_RTFReadObjectGroup(RTF_Info *info) RTFRouteToken(info); /* feed "}" back to router */ } +static void ME_RTFReadParnumGroup( RTF_Info *info ) +{ + int level = 1, type = -1; + WORD indent = 0, start = 1; + WCHAR txt_before = 0, txt_after = 0; + + for (;;) + { + RTFGetToken( info ); + + if (RTFCheckCMM( info, rtfControl, rtfDestination, rtfParNumTextBefore ) || + RTFCheckCMM( info, rtfControl, rtfDestination, rtfParNumTextAfter )) + { + int loc = info->rtfMinor; + + RTFGetToken( info ); + if (info->rtfClass == rtfText) + { + if (loc == rtfParNumTextBefore) + txt_before = info->rtfMajor; + else + txt_after = info->rtfMajor; + continue; + } + /* falling through to catch EOFs and group level changes */ + } + + if (info->rtfClass == rtfEOF) + return; + + if (RTFCheckCM( info, rtfGroup, rtfEndGroup )) + { + if (--level == 0) break; + continue; + } + + if (RTFCheckCM( info, rtfGroup, rtfBeginGroup )) + { + level++; + continue; + } + + /* Ignore non para-attr */ + if (!RTFCheckCM( info, rtfControl, rtfParAttr )) + continue; + + switch (info->rtfMinor) + { + case rtfParLevel: /* Para level is ignored */ + case rtfParSimple: + break; + case rtfParBullet: + type = PFN_BULLET; + break; + + case rtfParNumDecimal: + type = PFN_ARABIC; + break; + case rtfParNumULetter: + type = PFN_UCLETTER; + break; + case rtfParNumURoman: + type = PFN_UCROMAN; + break; + case rtfParNumLLetter: + type = PFN_LCLETTER; + break; + case rtfParNumLRoman: + type = PFN_LCROMAN; + break; + + case rtfParNumIndent: + indent = info->rtfParam; + break; + case rtfParNumStartAt: + start = info->rtfParam; + break; + } + } + + if (type != -1) + { + info->fmt.dwMask |= (PFM_NUMBERING | PFM_NUMBERINGSTART | PFM_NUMBERINGSTYLE | PFM_NUMBERINGTAB); + info->fmt.wNumbering = type; + info->fmt.wNumberingStart = start; + info->fmt.wNumberingStyle = PFNS_PAREN; + if (type != PFN_BULLET) + { + if (txt_before == 0 && txt_after == 0) + info->fmt.wNumberingStyle = PFNS_PLAIN; + else if (txt_after == '.') + info->fmt.wNumberingStyle = PFNS_PERIOD; + else if (txt_before == '(' && txt_after == ')') + info->fmt.wNumberingStyle = PFNS_PARENS; + } + info->fmt.wNumberingTab = indent; + } + + TRACE("type %d indent %d start %d txt before %04x txt after %04x\n", + type, indent, start, txt_before, txt_after); + + RTFRouteToken( info ); /* feed "}" back to router */ +} + static void ME_RTFReadHook(RTF_Info *info) { switch(info->rtfClass) @@ -1581,6 +1673,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre RTFSetDestinationCallback(&parser, rtfShpPict, ME_RTFReadShpPictGroup); RTFSetDestinationCallback(&parser, rtfPict, ME_RTFReadPictGroup); RTFSetDestinationCallback(&parser, rtfObject, ME_RTFReadObjectGroup); + RTFSetDestinationCallback(&parser, rtfParNumbering, ME_RTFReadParnumGroup); if (!parser.editor->bEmulateVersion10) /* v4.1 */ { RTFSetDestinationCallback(&parser, rtfNoNestTables, RTFSkipGroup); diff --git a/dlls/riched20/reader.c b/dlls/riched20/reader.c index 2e5dafd..a05b7fc 100644 --- a/dlls/riched20/reader.c +++ b/dlls/riched20/reader.c @@ -1774,8 +1774,8 @@ static RTFKey rtfKey[] = { rtfDestination, rtfFooterFirst, "footerf", 0 }, { rtfDestination, rtfParNumText, "pntext", 0 }, { rtfDestination, rtfParNumbering, "pn", 0 }, - { rtfDestination, rtfParNumTextAfter, "pntexta", 0 }, - { rtfDestination, rtfParNumTextBefore, "pntextb", 0 }, + { rtfDestination, rtfParNumTextAfter, "pntxta", 0 }, + { rtfDestination, rtfParNumTextBefore, "pntxtb", 0 }, { rtfDestination, rtfBookmarkStart, "bkmkstart", 0 }, { rtfDestination, rtfBookmarkEnd, "bkmkend", 0 }, { rtfDestination, rtfPict, "pict", 0 }, diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index ad51e64..d694d28 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -8414,6 +8414,74 @@ static void test_eop_char_fmt(void) DestroyWindow( edit ); } +static void test_para_numbering(void) +{ + HWND edit = new_richeditW( NULL ); + const char *numbers = "{\\rtf1{\\fonttbl{\\f0\\fswiss\\fprq2\\fcharset0 Arial;}{\\f1\\fnil\\fcharset2 Symbol;}}" + "\\pard{\\pntext\\f0 3.\\tab}{\\*\\pn\\pnlvlbody\\pnfs32\\pnf0\\pnindent1000\\pnstart2\\pndec{\\pntxta.}}" + "\\fs20\\fi200\\li360\\f0 First\\par" + "{\\pntext\\f0 4.\\tab}\\f0 Second\\par" + "{\\pntext\\f0 6.\\tab}\\f0 Third\\par}"; + const WCHAR expect_numbers_txt[] = {'F','i','r','s','t','\r','S','e','c','o','n','d','\r','T','h','i','r','d',0}; + EDITSTREAM es; + WCHAR buf[80]; + LRESULT result; + PARAFORMAT2 fmt, fmt2; + GETTEXTEX get_text; + CHARFORMAT2W cf; + + get_text.cb = sizeof(buf); + get_text.flags = GT_RAWTEXT; + get_text.codepage = 1200; + get_text.lpDefaultChar = NULL; + get_text.lpUsedDefChar = NULL; + + es.dwCookie = (DWORD_PTR)&numbers; + es.dwError = 0; + es.pfnCallback = test_EM_STREAMIN_esCallback; + result = SendMessageA( edit, EM_STREAMIN, SF_RTF, (LPARAM)&es ); + ok( result == lstrlenW( expect_numbers_txt ), "got %ld\n", result ); + + result = SendMessageW( edit, EM_GETTEXTEX, (WPARAM)&get_text, (LPARAM)buf ); + ok( result == lstrlenW( expect_numbers_txt ), "got %ld\n", result ); + ok( !lstrcmpW( buf, expect_numbers_txt ), "got %s\n", wine_dbgstr_w(buf) ); + + SendMessageW( edit, EM_SETSEL, 1, 1 ); + memset( &fmt, 0, sizeof(fmt) ); + fmt.cbSize = sizeof(fmt); + fmt.dwMask = PFM_ALL2; + SendMessageW( edit, EM_GETPARAFORMAT, 0, (LPARAM)&fmt ); + ok( fmt.wNumbering == PFN_ARABIC, "got %d\n", fmt.wNumbering ); + ok( fmt.wNumberingStart == 2, "got %d\n", fmt.wNumberingStart ); + ok( fmt.wNumberingStyle == PFNS_PERIOD, "got %04x\n", fmt.wNumberingStyle ); + ok( fmt.wNumberingTab == 1000, "got %d\n", fmt.wNumberingTab ); + ok( fmt.dxStartIndent == 560, "got %d\n", fmt.dxStartIndent ); + ok( fmt.dxOffset == -200, "got %d\n", fmt.dxOffset ); + + /* Second para should have identical fmt */ + SendMessageW( edit, EM_SETSEL, 10, 10 ); + memset( &fmt2, 0, sizeof(fmt2) ); + fmt2.cbSize = sizeof(fmt2); + fmt2.dwMask = PFM_ALL2; + SendMessageW( edit, EM_GETPARAFORMAT, 0, (LPARAM)&fmt2 ); + ok( !memcmp( &fmt, &fmt2, sizeof(fmt) ), "format mismatch\n" ); + + /* Check the eop heights - this determines the label height */ + SendMessageW( edit, EM_SETSEL, 12, 13 ); + cf.cbSize = sizeof(cf); + cf.dwMask = CFM_SIZE; + SendMessageW( edit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf ); + ok( cf.yHeight == 200, "got %d\n", cf.yHeight ); + + SendMessageW( edit, EM_SETSEL, 18, 19 ); + cf.cbSize = sizeof(cf); + cf.dwMask = CFM_SIZE; + SendMessageW( edit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf ); + ok( cf.yHeight == 200, "got %d\n", cf.yHeight ); + + DestroyWindow( edit ); +} + START_TEST( editor ) { BOOL ret; @@ -8486,6 +8554,7 @@ START_TEST( editor ) test_rtf_specials(); test_background(); test_eop_char_fmt(); + test_para_numbering(); /* Set the environment variable WINETEST_RICHED20 to keep windows * responsive and open for 30 seconds. This is useful for debugging. -- 2.8.2 From huw at codeweavers.com Fri Oct 7 04:49:33 2016 From: huw at codeweavers.com (Huw Davies) Date: Fri, 7 Oct 2016 10:49:33 +0100 Subject: [PATCH 4/8] riched20: Add the ability to create ME_Strings from constants. Message-ID: <1475833777-45995-4-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/editor.h | 1 + dlls/riched20/editstr.h | 1 + dlls/riched20/string.c | 37 ++++++++++++++++++++++++++++++++----- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index b0a8a1a..24c856b 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -100,6 +100,7 @@ void ME_DumpDocument(ME_TextBuffer *buffer) DECLSPEC_HIDDEN; /* string.c */ ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars) DECLSPEC_HIDDEN; ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars) DECLSPEC_HIDDEN; +ME_String *ME_MakeStringConst(const WCHAR *str, int len) DECLSPEC_HIDDEN; void ME_DestroyString(ME_String *s) DECLSPEC_HIDDEN; BOOL ME_AppendString(ME_String *s, const WCHAR *append, int len) DECLSPEC_HIDDEN; ME_String *ME_VSplitString(ME_String *orig, int nVPos) DECLSPEC_HIDDEN; diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index 35555a9..0e60a3d 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -58,6 +58,7 @@ typedef struct tagME_String { WCHAR *szData; int nLen, nBuffer; + void (*free)(struct tagME_String *); } ME_String; typedef struct tagME_FontCacheItem diff --git a/dlls/riched20/string.c b/dlls/riched20/string.c index ef06bac..47aceca 100644 --- a/dlls/riched20/string.c +++ b/dlls/riched20/string.c @@ -27,10 +27,37 @@ static int ME_GetOptimalBuffer(int nLen) return ((sizeof(WCHAR) * nLen) + 128) & ~63; } +static ME_String *make_string( void (*free)(ME_String *) ) +{ + ME_String *s = heap_alloc( sizeof(*s) ); + + if (s) s->free = free; + return s; +} + +/* Create a ME_String using the const string provided. + * str must exist for the lifetime of the returned ME_String. + */ +ME_String *ME_MakeStringConst(const WCHAR *str, int len) +{ + ME_String *s = make_string( NULL ); + if (!s) return NULL; + + s->szData = (WCHAR *)str; + s->nLen = len; + s->nBuffer = 0; + return s; +} + +static void heap_string_free(ME_String *s) +{ + heap_free( s->szData ); +} + /* Create a buffer (uninitialized string) of size nMaxChars */ static ME_String *ME_MakeStringB(int nMaxChars) { - ME_String *s = heap_alloc( sizeof(*s) ); + ME_String *s = make_string( heap_string_free ); if (!s) return NULL; s->nLen = nMaxChars; @@ -69,7 +96,7 @@ ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars) void ME_DestroyString(ME_String *s) { if (!s) return; - heap_free( s->szData ); + if (s->free) s->free( s ); heap_free( s ); } @@ -78,6 +105,7 @@ BOOL ME_InsertString(ME_String *s, int ofs, const WCHAR *insert, int len) DWORD new_len = s->nLen + len + 1; WCHAR *new; + assert( s->nBuffer ); /* Not a const string */ assert( ofs <= s->nLen ); if( new_len > s->nBuffer ) @@ -104,9 +132,7 @@ ME_String *ME_VSplitString(ME_String *orig, int charidx) { ME_String *s; - /*if (charidx<0) charidx = 0; - if (charidx>orig->nLen) charidx = orig->nLen; - */ + assert(orig->nBuffer); /* Not a const string */ assert(charidx>=0); assert(charidx<=orig->nLen); @@ -122,6 +148,7 @@ void ME_StrDeleteV(ME_String *s, int nVChar, int nChars) { int end_ofs = nVChar + nChars; + assert(s->nBuffer); /* Not a const string */ assert(nChars >= 0); assert(nVChar >= 0); assert(end_ofs <= s->nLen); -- 2.8.2 From huw at codeweavers.com Fri Oct 7 04:49:34 2016 From: huw at codeweavers.com (Huw Davies) Date: Fri, 7 Oct 2016 10:49:34 +0100 Subject: [PATCH 5/8] riched20: Maintain a ptr to the end-of-paragraph run. Message-ID: <1475833777-45995-5-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/editstr.h | 1 + dlls/riched20/para.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index 0e60a3d..fb88f71 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -201,6 +201,7 @@ typedef struct tagME_Paragraph POINT pt; int nHeight, nWidth; int nRows; + ME_Run *eop_run; /* ptr to the end-of-para run */ struct tagME_DisplayItem *prev_para, *next_para; } ME_Paragraph; diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index e246e37..0174252 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -81,6 +81,8 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor) run->member.run.len = eol_len; run->member.run.para = ¶->member.para; + para->member.para.eop_run = &run->member.run; + ME_InsertBefore(text->pLast, para); ME_InsertBefore(text->pLast, run); para->member.para.prev_para = text->pFirst; @@ -272,6 +274,10 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME_InsertBefore(run, new_para); ME_InsertBefore(new_para, end_run); + /* Fix up the paras' eop_run ptrs */ + new_para->member.para.eop_run = run_para->member.para.eop_run; + run_para->member.para.eop_run = &end_run->member.run; + if (!editor->bEmulateVersion10) { /* v4.1 */ if (paraFlags & (MEPF_ROWSTART|MEPF_CELL)) { @@ -429,6 +435,9 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp, pTmp->member.run.para = &tp->member.para; } while(1); + /* Fix up the para's eop_run ptr */ + tp->member.para.eop_run = pNext->member.para.eop_run; + ME_Remove(pRun); ME_DestroyDisplayItem(pRun); -- 2.8.2 From huw at codeweavers.com Fri Oct 7 04:49:35 2016 From: huw at codeweavers.com (Huw Davies) Date: Fri, 7 Oct 2016 10:49:35 +0100 Subject: [PATCH 6/8] riched20: Add support for displaying bulleted lists. Message-ID: <1475833777-45995-6-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/editor.h | 2 ++ dlls/riched20/editstr.h | 9 +++++++++ dlls/riched20/list.c | 1 + dlls/riched20/paint.c | 20 ++++++++++++++++++++ dlls/riched20/para.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ dlls/riched20/wrap.c | 33 +++++++++++++++++++++++++++++---- 6 files changed, 110 insertions(+), 4 deletions(-) diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index 24c856b..7d46692 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -217,6 +217,8 @@ BOOL ME_SetSelectionParaFormat(ME_TextEditor *editor, const PARAFORMAT2 *pFmt) D void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN; void ME_MarkAllForWrapping(ME_TextEditor *editor) DECLSPEC_HIDDEN; void ME_SetDefaultParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN; +void para_num_init( ME_Context *c, ME_Paragraph *para ) DECLSPEC_HIDDEN; +void para_num_clear( struct para_num *pn ) DECLSPEC_HIDDEN; /* paint.c */ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) DECLSPEC_HIDDEN; diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index fb88f71..eb4d9f5 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -188,6 +188,14 @@ typedef struct tagME_BorderRect ME_Border right; } ME_BorderRect; +struct para_num +{ + ME_Style *style; + ME_String *text; + INT width; + POINT pt; +}; + typedef struct tagME_Paragraph { PARAFORMAT2 fmt; @@ -201,6 +209,7 @@ typedef struct tagME_Paragraph POINT pt; int nHeight, nWidth; int nRows; + struct para_num para_num; ME_Run *eop_run; /* ptr to the end-of-para run */ struct tagME_DisplayItem *prev_para, *next_para; } ME_Paragraph; diff --git a/dlls/riched20/list.c b/dlls/riched20/list.c index 15b944c..d321446 100644 --- a/dlls/riched20/list.c +++ b/dlls/riched20/list.c @@ -164,6 +164,7 @@ void ME_DestroyDisplayItem(ME_DisplayItem *item) if (item->type==diParagraph) { ME_DestroyString(item->member.para.text); + para_num_clear( &item->member.para.para_num ); } if (item->type==diRun) diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c index 8e51772..7c17513 100644 --- a/dlls/riched20/paint.c +++ b/dlls/riched20/paint.c @@ -898,6 +898,25 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) } } +static void draw_para_number( ME_Context *c, ME_DisplayItem *p ) +{ + ME_Paragraph *para = &p->member.para; + HFONT old_font; + int x, y; + + if (para->fmt.wNumbering) + { + old_font = ME_SelectStyleFont( c, para->para_num.style ); + + x = c->pt.x + para->para_num.pt.x; + y = c->pt.y + para->pt.y + para->para_num.pt.y; + + ExtTextOutW( c->hDC, x, y, 0, NULL, para->para_num.text->szData, para->para_num.text->nLen, NULL ); + + ME_UnselectStyleFont( c, para->para_num.style, old_font ); + } +} + static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) { int align = SetTextAlign(c->hDC, TA_BASELINE); @@ -1023,6 +1042,7 @@ static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) } ME_DrawTableBorders(c, paragraph); + draw_para_number(c, paragraph); SetTextAlign(c->hDC, align); } diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index 0174252..3c62da2 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -128,6 +128,55 @@ static void ME_UpdateTableFlags(ME_DisplayItem *para) para->member.para.fmt.wEffects &= ~PFE_TABLE; } +void para_num_init( ME_Context *c, ME_Paragraph *para ) +{ + ME_Style *style; + CHARFORMAT2W cf; + static const WCHAR bullet_font[] = {'S','y','m','b','o','l',0}; + static const WCHAR bullet_str[] = {0xb7, 0}; + static const WCHAR spaceW[] = {' ', 0}; + HFONT old_font; + SIZE sz; + + if (para->para_num.style && para->para_num.text) return; + + if (!para->para_num.style) + { + style = para->eop_run->style; + + cf.cbSize = sizeof(cf); + cf.dwMask = CFM_FACE | CFM_CHARSET; + memcpy( cf.szFaceName, bullet_font, sizeof(bullet_font) ); + cf.bCharSet = SYMBOL_CHARSET; + style = ME_ApplyStyle( c->editor, style, &cf ); + + para->para_num.style = style; + } + + if (!para->para_num.text) + { + para->para_num.text = ME_MakeStringConst( bullet_str, 1 ); + } + + old_font = ME_SelectStyleFont( c, para->para_num.style ); + GetTextExtentPointW( c->hDC, para->para_num.text->szData, para->para_num.text->nLen, &sz ); + para->para_num.width = sz.cx; + GetTextExtentPointW( c->hDC, spaceW, 1, &sz ); + para->para_num.width += sz.cx; + ME_UnselectStyleFont( c, para->para_num.style, old_font ); +} + +void para_num_clear( struct para_num *pn ) +{ + if (pn->style) + { + ME_ReleaseStyle( pn->style ); + pn->style = NULL; + } + ME_DestroyString( pn->text ); + pn->text = NULL; +} + static BOOL ME_SetParaFormat(ME_TextEditor *editor, ME_Paragraph *para, const PARAFORMAT2 *pFmt) { PARAFORMAT2 copy; diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index 4c73c5d..e3a70f0 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -37,8 +37,10 @@ typedef struct tagME_WrapContext { ME_Style *style; ME_Context *context; - int nLeftMargin, nRightMargin, nFirstMargin; - int nAvailWidth; + int nLeftMargin, nRightMargin; + int nFirstMargin; /* Offset to first line's text, always to the text itself even if a para number is present */ + int nParaNumOffset; /* Offset to the para number */ + int nAvailWidth; /* Width avail for text to wrap into. Does not include any para number text */ int nRow; POINT pt; BOOL bOverflown, bWordWrap; @@ -303,7 +305,12 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd) BOOL bSkippingSpaces = TRUE; int ascent = 0, descent = 0, width=0, shift = 0, align = 0; - /* wrap text */ + /* Include height of para numbering label */ + if (wc->nRow == 0 && para->fmt.wNumbering) + { + ascent = para->para_num.style->tm.tmAscent; + descent = para->para_num.style->tm.tmDescent; + } for (p = pEnd->prev; p!=wc->pRowStart->prev; p = p->prev) { @@ -367,6 +374,13 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd) p->member.run.pt.x += row->member.row.nLMargin+shift; } } + + if (wc->nRow == 0 && para->fmt.wNumbering) + { + para->para_num.pt.x = wc->nParaNumOffset + shift; + para->para_num.pt.y = wc->pt.y + row->member.row.nBaseline; + } + ME_InsertBefore(wc->pRowStart, row); wc->nRow++; wc->pt.y += row->member.row.nHeight; @@ -869,6 +883,9 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) { } ME_PrepareParagraphForWrapping(c, tp); + /* Calculate paragraph numbering label */ + para_num_init( c, &tp->member.para ); + /* For now treating all non-password text as complex for better testing */ if (!c->editor->cPasswordMask /* && ScriptIsComplex( tp->member.para.text->szData, tp->member.para.text->nLen, SIC_COMPLEX ) == S_OK */) @@ -883,6 +900,7 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) { wc.pPara = tp; /* wc.para_style = tp->member.para.style; */ wc.style = NULL; + wc.nParaNumOffset = 0; if (tp->member.para.nFlags & MEPF_ROWEND) { wc.nFirstMargin = wc.nLeftMargin = wc.nRightMargin = 0; } else { @@ -890,8 +908,15 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) { if (tp->member.para.pCell) { dxStartIndent += ME_GetTableRowEnd(tp)->member.para.fmt.dxOffset; } + wc.nLeftMargin = ME_twips2pointsX(c, dxStartIndent + pFmt->dxOffset); wc.nFirstMargin = ME_twips2pointsX(c, dxStartIndent); - wc.nLeftMargin = wc.nFirstMargin + ME_twips2pointsX(c, pFmt->dxOffset); + if (pFmt->wNumbering) + { + wc.nParaNumOffset = wc.nFirstMargin; + dxStartIndent = max( ME_twips2pointsX(c, pFmt->wNumberingTab), + tp->member.para.para_num.width ); + wc.nFirstMargin += dxStartIndent; + } wc.nRightMargin = ME_twips2pointsX(c, pFmt->dxRightIndent); if (wc.nFirstMargin < 0) -- 2.8.2 From huw at codeweavers.com Fri Oct 7 04:49:36 2016 From: huw at codeweavers.com (Huw Davies) Date: Fri, 7 Oct 2016 10:49:36 +0100 Subject: [PATCH 7/8] riched20: Update the paragraph numbering style if the end-of-paragraph style changes. Message-ID: <1475833777-45995-7-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/run.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index 984f8f5..496f0f9 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -753,12 +753,20 @@ void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, C for (run = start_run; run != end_run; run = ME_FindItemFwd( run, diRun )) { ME_Style *new_style = ME_ApplyStyle(editor, run->member.run.style, pFmt); + ME_Paragraph *para = run->member.run.para; add_undo_set_char_fmt( editor, run->member.run.para->nCharOfs + run->member.run.nCharOfs, run->member.run.len, &run->member.run.style->fmt ); ME_ReleaseStyle(run->member.run.style); run->member.run.style = new_style; - run->member.run.para->nFlags |= MEPF_REWRAP; + + /* The para numbering style depends on the eop style */ + if ((run->member.run.nFlags & MERF_ENDPARA) && para->para_num.style) + { + ME_ReleaseStyle(para->para_num.style); + para->para_num.style = NULL; + } + para->nFlags |= MEPF_REWRAP; } } -- 2.8.2 From huw at codeweavers.com Fri Oct 7 04:49:37 2016 From: huw at codeweavers.com (Huw Davies) Date: Fri, 7 Oct 2016 10:49:37 +0100 Subject: [PATCH 8/8] wordpad: Improve the indentation of bulleted lists. Message-ID: <1475833777-45995-8-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- programs/wordpad/wordpad.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/programs/wordpad/wordpad.c b/programs/wordpad/wordpad.c index bb34f2e..ea6e11d 100644 --- a/programs/wordpad/wordpad.c +++ b/programs/wordpad/wordpad.c @@ -2353,22 +2353,28 @@ static LRESULT OnCommand( HWND hWnd, WPARAM wParam, LPARAM lParam) case ID_BULLET: { - PARAFORMAT pf; + PARAFORMAT2 pf; pf.cbSize = sizeof(pf); pf.dwMask = PFM_NUMBERING; SendMessageW(hwndEditor, EM_GETPARAFORMAT, 0, (LPARAM)&pf); - pf.dwMask |= PFM_OFFSET; + pf.dwMask = PFM_NUMBERING | PFM_NUMBERINGSTART | PFM_NUMBERINGTAB | PFM_OFFSET | PFM_OFFSETINDENT; if(pf.wNumbering == PFN_BULLET) { pf.wNumbering = 0; + pf.wNumberingStart = 0; + pf.wNumberingTab = 0; pf.dxOffset = 0; + pf.dxStartIndent = -360; } else { pf.wNumbering = PFN_BULLET; - pf.dxOffset = 720; + pf.wNumberingStart = 1; + pf.wNumberingTab = 360; + pf.dxOffset = 360; + pf.dxStartIndent = 360; } SendMessageW(hwndEditor, EM_SETPARAFORMAT, 0, (LPARAM)&pf); -- 2.8.2 From hverbeet at codeweavers.com Fri Oct 7 05:49:54 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 7 Oct 2016 12:49:54 +0200 Subject: [v2 PATCH] d2d1/tests: Initial tests for bitmap render target In-Reply-To: <20161006124952.31244-1-nsivov@codeweavers.com> References: <20161006124952.31244-1-nsivov@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 7 05:50:16 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 7 Oct 2016 12:50:16 +0200 Subject: [PATCH 1/5] wined3d: Slightly offset the viewport in the ARB_clip_control case. In-Reply-To: <1475794673-28114-1-git-send-email-mbruni@codeweavers.com> References: <1475794673-28114-1-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 7 05:50:17 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 7 Oct 2016 12:50:17 +0200 Subject: [PATCH 2/5] wined3d: Account for offscreen rendering in the pixel shader key only if vpos is used. In-Reply-To: <1475794673-28114-2-git-send-email-mbruni@codeweavers.com> References: <1475794673-28114-2-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 7 05:50:18 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 7 Oct 2016 12:50:18 +0200 Subject: [PATCH 3/5] wined3d: Flag WINED3D_SHADER_CONST_PS_Y_CORR on framebuffer changes. In-Reply-To: <1475794673-28114-3-git-send-email-mbruni@codeweavers.com> References: <1475794673-28114-3-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 7 05:50:20 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 7 Oct 2016 12:50:20 +0200 Subject: [PATCH 5/5] d3d9/tests: Add a test for the dsy SM3 instruction. In-Reply-To: <1475794673-28114-5-git-send-email-mbruni@codeweavers.com> References: <1475794673-28114-5-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 7 05:50:19 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 7 Oct 2016 12:50:19 +0200 Subject: [PATCH 4/5] d3d9/tests: Make the window client rect match the d3d swapchain size. In-Reply-To: <1475794673-28114-4-git-send-email-mbruni@codeweavers.com> References: <1475794673-28114-4-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From wine.dev at web.de Fri Oct 7 09:01:49 2016 From: wine.dev at web.de (Detlef Riekenberg) Date: Fri, 7 Oct 2016 16:01:49 +0200 Subject: [PATCH] kernel32/tests: Use case insensitive compare for filename Message-ID: <1475848909-5559-1-git-send-email-wine.dev@web.de> There is also no need to compare every character seperate. Fixes: http://test.winehq.org/data/5d96ef42a58e09a2d6cf47a685abb3f42b513ceb/win7_dr-w7sp1-p6100-wow/kernel32:file.html Introduced by: http://source.winehq.org/git/wine.git/commitdiff/68b654ad2fe18aad6b9b0d0128656753f6639442 Signed-off-by: Detlef Riekenberg -- bye bye ... Detlef --- dlls/kernel32/tests/file.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index f039cf9..00e2a71 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -3834,6 +3834,7 @@ static void test_GetFileInformationByHandleEx(void) { int i; char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[1024], *strPtr; + char astr[MAX_PATH]; BOOL ret; DWORD ret2, written; HANDLE directory, file; @@ -3967,9 +3968,14 @@ static void test_GetFileInformationByHandleEx(void) ok(strPtr != NULL, "GetFileInformationByHandleEx: Temp filename didn't contain backslash\n"); ok(nameInfo->FileNameLength == strlen(strPtr) * 2, "GetFileInformationByHandleEx: Incorrect file name length\n"); - for (i = 0; i < nameInfo->FileNameLength/2; i++) - ok(strPtr[i] == nameInfo->FileName[i], "Incorrect filename char %d: %c vs %c\n", - i, strPtr[i], nameInfo->FileName[i]); + + WideCharToMultiByte(CP_ACP, 0, nameInfo->FileName, nameInfo->FileNameLength/2, astr, sizeof(astr), NULL, NULL); + if (nameInfo->FileNameLength < sizeof(astr)) + astr[nameInfo->FileNameLength] = 0; + else + astr[sizeof(astr)-1] = 0; + + ok(!lstrcmpiA(strPtr, astr), "got %s, expected %s\n", astr, strPtr); /* invalid classes */ SetLastError(0xdeadbeef); -- 2.7.4 From andrey.goosev at gmail.com Fri Oct 7 09:02:36 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Fri, 7 Oct 2016 17:02:36 +0300 Subject: wined3d: Add missing '\n' to FIXME() messages. (v2) Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: wined3d-Add-missing-n-to-FIXME-messages.-v2.patch Type: text/x-patch Size: 1475 bytes Desc: not available URL: From jacek at codeweavers.com Fri Oct 7 09:04:49 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Fri, 7 Oct 2016 16:04:49 +0200 Subject: mshtml: Update binding moniker in handle_redirect. Message-ID: <6c66477e-2123-52a7-fd93-ae33a717f544@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/mshtml/navigate.c | 7 +++++++ 1 file changed, 7 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-mshtml-Update-binding-moniker-in-handle_redirect.diff Type: text/x-patch Size: 709 bytes Desc: not available URL: From aric at codeweavers.com Fri Oct 7 10:02:16 2016 From: aric at codeweavers.com (Aric Stewart) Date: Fri, 7 Oct 2016 10:02:16 -0500 Subject: [PATCH 1/2] winebus.sys: Implement IOCTL_HID_GET_DEVICE_DESCRIPTOR for hidraw Message-ID: <23dce466-5329-645c-84d2-d9d76adbd5ec@codeweavers.com> Signed-off-by: Aric Stewart --- configure | 1 + configure.ac | 1 + dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_udev.c | 58 ++++++++++++++++++++++++++++++++++++++++++--- dlls/winebus.sys/main.c | 41 ++++++++++++++++++++++++++++++++ include/config.h.in | 3 +++ 6 files changed, 102 insertions(+), 3 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-winebus.sys-Implement-IOCTL_HID_GET_DEVICE_DESCRIPTOR-.txt Type: text/x-patch Size: 7120 bytes Desc: not available URL: From aric at codeweavers.com Fri Oct 7 10:02:57 2016 From: aric at codeweavers.com (Aric Stewart) Date: Fri, 7 Oct 2016 10:02:57 -0500 Subject: [PATCH 2/2] winebus.sys: Implement IOCTL_HID_GET_REPORT_DESCRIPTOR for hidraw Message-ID: <697642f0-4d11-62c8-ceb9-681ffb7aba3b@codeweavers.com> Signed-off-by: Aric Stewart --- dlls/winebus.sys/main.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-winebus.sys-Implement-IOCTL_HID_GET_REPORT_DESCRIPTOR-.txt Type: text/x-patch Size: 1170 bytes Desc: not available URL: From jacek at codeweavers.com Fri Oct 7 11:13:59 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Fri, 7 Oct 2016 18:13:59 +0200 Subject: mshtml: Added support for non-pixel style values in IHTMLStyle::get_pixel* functions. Message-ID: <9a38c0c8-df50-5a2b-d5b9-beb9dab44afc@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/mshtml/htmlstyle.c | 11 +++-------- dlls/mshtml/tests/style.c | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 8 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-mshtml-Added-support-for-non-pixel-style-values-in-IH.diff Type: text/x-patch Size: 2991 bytes Desc: not available URL: From jre.winesim at gmail.com Fri Oct 7 11:39:21 2016 From: jre.winesim at gmail.com (Jens Reyer) Date: Fri, 7 Oct 2016 18:39:21 +0200 Subject: [PATCH v3 1/6] libport: Don't call exit in the shared library. In-Reply-To: <20161007163926.21375-1-jre.winesim@gmail.com> References: <20161007163926.21375-1-jre.winesim@gmail.com> Message-ID: <20161007163926.21375-2-jre.winesim@gmail.com> From: Michael Gilbert Signed-off-by: Jens Reyer --- libs/port/spawn.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/port/spawn.c b/libs/port/spawn.c index 97364e7..c1a95a2 100644 --- a/libs/port/spawn.c +++ b/libs/port/spawn.c @@ -55,20 +55,20 @@ int _spawnvp(int mode, const char *cmdname, const char *const argv[]) if (mode == _P_DETACH) { pid = fork(); - if (pid == -1) _exit(1); - else if (pid > 0) _exit(0); + if (pid == -1) abort(); + else if (pid > 0) return pid; /* else in grandchild */ } signal( SIGPIPE, SIG_DFL ); execvp(cmdname, (char **)argv); - _exit(1); + abort(); } if (pid == -1) return -1; - if (mode == _P_OVERLAY) exit(0); + if (mode == _P_OVERLAY) abort(); if (mode == _P_WAIT || mode == _P_DETACH) { -- 2.9.3 From jre.winesim at gmail.com Fri Oct 7 11:39:22 2016 From: jre.winesim at gmail.com (Jens Reyer) Date: Fri, 7 Oct 2016 18:39:22 +0200 Subject: [PATCH v3 2/6] libwine: Don't call exit in the shared library. In-Reply-To: <20161007163926.21375-1-jre.winesim@gmail.com> References: <20161007163926.21375-1-jre.winesim@gmail.com> Message-ID: <20161007163926.21375-3-jre.winesim@gmail.com> From: Michael Gilbert Signed-off-by: Jens Reyer --- libs/wine/config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/wine/config.c b/libs/wine/config.c index 3b5dd68..c0b3bdd 100644 --- a/libs/wine/config.c +++ b/libs/wine/config.c @@ -68,7 +68,7 @@ static void fatal_error( const char *err, ... ) fprintf( stderr, "wine: " ); vfprintf( stderr, err, args ); va_end( args ); - exit(1); + abort(); } /* die on a fatal error */ @@ -81,7 +81,7 @@ static void fatal_perror( const char *err, ... ) vfprintf( stderr, err, args ); perror( " " ); va_end( args ); - exit(1); + abort(); } /* malloc wrapper */ -- 2.9.3 From jre.winesim at gmail.com Fri Oct 7 11:39:23 2016 From: jre.winesim at gmail.com (Jens Reyer) Date: Fri, 7 Oct 2016 18:39:23 +0200 Subject: [PATCH v3 3/6] libwine: Don't call exit in the shared library. In-Reply-To: <20161007163926.21375-1-jre.winesim@gmail.com> References: <20161007163926.21375-1-jre.winesim@gmail.com> Message-ID: <20161007163926.21375-4-jre.winesim@gmail.com> From: Michael Gilbert Signed-off-by: Jens Reyer --- libs/wine/debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/wine/debug.c b/libs/wine/debug.c index 8b04ef9..6ed70b7 100644 --- a/libs/wine/debug.c +++ b/libs/wine/debug.c @@ -186,7 +186,7 @@ static void debug_usage(void) " turns on all messages except warning heap messages\n" "Available message classes: err, warn, fixme, trace\n"; write( 2, usage, sizeof(usage) - 1 ); - exit(1); + abort(); } -- 2.9.3 From jre.winesim at gmail.com Fri Oct 7 11:39:24 2016 From: jre.winesim at gmail.com (Jens Reyer) Date: Fri, 7 Oct 2016 18:39:24 +0200 Subject: [PATCH v3 4/6] libwine: Don't call exit in the shared library. In-Reply-To: <20161007163926.21375-1-jre.winesim@gmail.com> References: <20161007163926.21375-1-jre.winesim@gmail.com> Message-ID: <20161007163926.21375-5-jre.winesim@gmail.com> From: Michael Gilbert Signed-off-by: Jens Reyer --- libs/wine/ldt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c index 0946407..8bdda00 100644 --- a/libs/wine/ldt.c +++ b/libs/wine/ldt.c @@ -192,7 +192,7 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry ) { perror("i386_set_ldt"); fprintf( stderr, "Did you reconfigure the kernel with \"options USER_LDT\"?\n" ); - exit(1); + abort(); } } #elif defined(__svr4__) || defined(_SCO_DS) @@ -213,7 +213,7 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry ) perror("i386_set_ldt"); #else fprintf( stderr, "No LDT support on this platform\n" ); - exit(1); + abort(); #endif if (ret >= 0) -- 2.9.3 From jre.winesim at gmail.com Fri Oct 7 11:39:25 2016 From: jre.winesim at gmail.com (Jens Reyer) Date: Fri, 7 Oct 2016 18:39:25 +0200 Subject: [PATCH v3 5/6] libwine: Don't call exit in the shared library. In-Reply-To: <20161007163926.21375-1-jre.winesim@gmail.com> References: <20161007163926.21375-1-jre.winesim@gmail.com> Message-ID: <20161007163926.21375-6-jre.winesim@gmail.com> From: Michael Gilbert Signed-off-by: Jens Reyer --- libs/wine/mmap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/wine/mmap.c b/libs/wine/mmap.c index 1a3ca59..588924d 100644 --- a/libs/wine/mmap.c +++ b/libs/wine/mmap.c @@ -76,7 +76,7 @@ static inline int get_fdzero(void) if ((fd = open( "/dev/zero", O_RDONLY )) == -1) { perror( "/dev/zero: open" ); - exit(1); + abort(); } } return fd; @@ -128,7 +128,7 @@ static int try_mmap_fixed (void *addr, size_t len, int prot, int flags, if ( (pid = vfork()) == -1 ) { perror("try_mmap_fixed: vfork"); - exit(1); + abort(); } if ( pid == 0 ) { @@ -140,18 +140,18 @@ static int try_mmap_fixed (void *addr, size_t len, int prot, int flags, mapped and we must fail. */ for ( i = 0; i < len; i += pagesize ) if ( mincore( (caddr_t)addr + i, pagesize, &vec ) != -1 ) - _exit(1); + abort(); /* Perform the mapping with MAP_FIXED set. This is safe now, as none of the pages is currently in use. */ result = mmap( addr, len, prot, flags | MAP_FIXED, fildes, off ); if ( result == addr ) - _exit(0); + break; if ( result != (void *) -1 ) /* This should never happen ... */ munmap( result, len ); - _exit(1); + abort(); } /* reap child */ -- 2.9.3 From jre.winesim at gmail.com Fri Oct 7 11:39:26 2016 From: jre.winesim at gmail.com (Jens Reyer) Date: Fri, 7 Oct 2016 18:39:26 +0200 Subject: [PATCH v3 6/6] wpp: Don't call exit in the shared library. In-Reply-To: <20161007163926.21375-1-jre.winesim@gmail.com> References: <20161007163926.21375-1-jre.winesim@gmail.com> Message-ID: <20161007163926.21375-7-jre.winesim@gmail.com> From: Michael Gilbert Signed-off-by: Jens Reyer --- libs/wpp/preproc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/wpp/preproc.c b/libs/wpp/preproc.c index 21830d6..b0de2e0 100644 --- a/libs/wpp/preproc.c +++ b/libs/wpp/preproc.c @@ -711,7 +711,7 @@ end: static void wpp_default_error(const char *file, int line, int col, const char *near, const char *msg, va_list ap) { generic_msg(msg, "Error", near, ap); - exit(1); + abort(); } static void wpp_default_warning(const char *file, int line, int col, const char *near, const char *msg, va_list ap) @@ -759,5 +759,5 @@ void pp_internal_error(const char *file, int line, const char *s, ...) vfprintf(stderr, s, ap); fprintf(stderr, "\n"); va_end(ap); - exit(3); + abort(); } -- 2.9.3 From jre.winesim at gmail.com Fri Oct 7 11:39:20 2016 From: jre.winesim at gmail.com (Jens Reyer) Date: Fri, 7 Oct 2016 18:39:20 +0200 Subject: [PATCH v3 0/6] Don't call exit in the shared library. Message-ID: <20161007163926.21375-1-jre.winesim@gmail.com> Hi, this patch series replaces calls of "exit" in the shared library with "abort" for failures, and "break" or "return" for non-failures. We were hinted to this in Debian by the QA tool lintian (https://lintian.debian.org/tags/shlib-calls-exit.html): The shared library libwine.so.1.0 calls the C library exit() or _exit() functions. In the case of an error, the library should instead return an appropriate error code to the calling program which can then determine how to handle the error, including performing any required clean-up. In most cases, removing the call should be discussed with upstream, particularly as it may produce an ABI change. We apply this patch in its current form since Wine 1.7.44, and I'm not aware of any issues. At the same time I admit, that I don't grasp it totally, e.g. the changes in libport and wpp don't seem to be necessary to avoid the lintian hint. I welcome any feedback and review. v1: use asserts for mmap failure modes https://www.winehq.org/pipermail/wine-devel/2014-December/106096.html v2: use abort instead of exit for shared library failure modes https://www.winehq.org/pipermail/wine-devel/2015-July/108555.html v3: rebase v2, split commits per file I'm submitting this on behalf of its original author Michael Gilbert. It's part of Debian's packaging and licensed LGPL-2.1+. Michael Gilbert (6): libport: Don't call exit in the shared library. libwine: Don't call exit in the shared library. libwine: Don't call exit in the shared library. libwine: Don't call exit in the shared library. libwine: Don't call exit in the shared library. wpp: Don't call exit in the shared library. libs/port/spawn.c | 8 ++++---- libs/wine/config.c | 4 ++-- libs/wine/debug.c | 2 +- libs/wine/ldt.c | 4 ++-- libs/wine/mmap.c | 10 +++++----- libs/wpp/preproc.c | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) -- 2.9.3 From madewokherd at gmail.com Fri Oct 7 16:03:42 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Fri, 7 Oct 2016 16:03:42 -0500 Subject: [1/3] gdiplus: Add FIXME for EMF records we need to implement. Message-ID: <1475874224-15291-1-git-send-email-madewokherd@gmail.com> From: Vincent Povirk These records cause state tracking in gdi32, but the state tracking doesn't work correctly because we didn't pass a DC to EnumEnhMetaFile. Since native updates transforms immediately (see patch 2), while gdi32 updates it only when returning from a callback, gdi's state tracking wouldn't help us anyway. We have to do this within GdipPlayMetafileRecord. Signed-off-by: Vincent Povirk --- dlls/gdiplus/metafile.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index 9de584c..803384a 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -1131,6 +1131,26 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, { ENHMETARECORD *record; + switch (recordType) + { + case EMR_SETMAPMODE: + case EMR_SAVEDC: + case EMR_RESTOREDC: + case EMR_SETWINDOWORGEX: + case EMR_SETWINDOWEXTEX: + case EMR_SETVIEWPORTORGEX: + case EMR_SETVIEWPORTEXTEX: + case EMR_EXTSELECTCLIPRGN: + case EMR_SETWORLDTRANSFORM: + case EMR_SCALEVIEWPORTEXTEX: + case EMR_SCALEWINDOWEXTEX: + case EMR_MODIFYWORLDTRANSFORM: + FIXME("not implemented for record type %x\n", recordType); + break; + default: + break; + } + record = heap_alloc_zero(dataSize + 8); if (record) -- 2.7.4 From madewokherd at gmail.com Fri Oct 7 16:03:43 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Fri, 7 Oct 2016 16:03:43 -0500 Subject: [2/3] gdiplus: Add test for gdi32 SetWorldTransform record. Message-ID: <1475874224-15291-2-git-send-email-madewokherd@gmail.com> From: Vincent Povirk Signed-off-by: Vincent Povirk --- dlls/gdiplus/tests/metafile.c | 136 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 132 insertions(+), 4 deletions(-) diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c index 7251ff3..8531ce5 100644 --- a/dlls/gdiplus/tests/metafile.c +++ b/dlls/gdiplus/tests/metafile.c @@ -36,6 +36,8 @@ typedef struct emfplus_record BOOL todo; ULONG record_type; BOOL playback_todo; + void (*playback_fn)(GpMetafile* metafile, EmfPlusRecordType record_type, + unsigned int flags, unsigned int dataSize, const unsigned char *pStr); } emfplus_record; typedef struct emfplus_check_state @@ -205,12 +207,19 @@ static BOOL CALLBACK play_metafile_proc(EmfPlusRecordType record_type, unsigned emfplus_check_state *state = (emfplus_check_state*)userdata; GpStatus stat; - stat = GdipPlayMetafileRecord(state->metafile, record_type, flags, dataSize, pStr); - if (state->expected[state->count].record_type) { - todo_wine_if (state->expected[state->count].playback_todo) - ok(stat == Ok, "%s.%i: GdipPlayMetafileRecord failed with stat %i\n", state->desc, state->count, stat); + BOOL match = (state->expected[state->count].record_type == record_type); + + if (match && state->expected[state->count].playback_fn) + state->expected[state->count].playback_fn(state->metafile, record_type, flags, dataSize, pStr); + else + { + stat = GdipPlayMetafileRecord(state->metafile, record_type, flags, dataSize, pStr); + todo_wine_if (state->expected[state->count].playback_todo) + ok(stat == Ok, "%s.%i: GdipPlayMetafileRecord failed with stat %i\n", state->desc, state->count, stat); + } + todo_wine_if (state->expected[state->count].todo) ok(state->expected[state->count].record_type == record_type, "%s.%i: expected record type 0x%x, got 0x%x\n", state->desc, state->count, @@ -2145,6 +2154,124 @@ static void test_clipping(void) expect(Ok, stat); } +static void test_gditransform_cb(GpMetafile* metafile, EmfPlusRecordType record_type, + unsigned int flags, unsigned int dataSize, const unsigned char *pStr) +{ + static const XFORM xform = {0.5, 0, 0, 0.5, 0, 0}; + static const RECTL rectangle = {0,0,100,100}; + GpStatus stat; + + stat = GdipPlayMetafileRecord(metafile, EMR_SETWORLDTRANSFORM, 0, sizeof(xform), (void*)&xform); + expect(Ok, stat); + + stat = GdipPlayMetafileRecord(metafile, EMR_RECTANGLE, 0, sizeof(rectangle), (void*)&rectangle); + expect(Ok, stat); +} + +static const emfplus_record gditransform_records[] = { + {0, EMR_HEADER}, + {0, EMR_CREATEBRUSHINDIRECT}, + {0, EMR_SELECTOBJECT}, + {0, EMR_GDICOMMENT, 0, test_gditransform_cb}, + {0, EMR_SELECTOBJECT}, + {0, EMR_DELETEOBJECT}, + {0, EMR_EOF}, + {0} +}; + +static void test_gditransform(void) +{ + GpStatus stat; + GpMetafile *metafile; + GpGraphics *graphics; + HDC hdc, metafile_dc; + HENHMETAFILE hemf; + MetafileHeader header; + static const GpRectF frame = {0.0, 0.0, 100.0, 100.0}; + static const GpPointF dst_points[3] = {{0.0,0.0},{40.0,0.0},{0.0,40.0}}; + static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0}; + HBRUSH hbrush, holdbrush; + GpBitmap *bitmap; + ARGB color; + + hdc = CreateCompatibleDC(0); + + stat = GdipRecordMetafile(hdc, EmfTypeEmfOnly, &frame, MetafileFrameUnitPixel, description, &metafile); + expect(Ok, stat); + + DeleteDC(hdc); + + if (stat != Ok) + return; + + stat = GdipGetHemfFromMetafile(metafile, &hemf); + expect(InvalidParameter, stat); + + memset(&header, 0xaa, sizeof(header)); + stat = GdipGetMetafileHeaderFromMetafile(metafile, &header); + expect(Ok, stat); + expect(MetafileTypeEmf, header.Type); + ok(header.Version == 0xdbc01001 || header.Version == 0xdbc01002, "Unexpected version %x\n", header.Version); + + stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics); + expect(Ok, stat); + + stat = GdipGetDC(graphics, &metafile_dc); + expect(Ok, stat); + + if (stat != Ok) + { + GdipDeleteGraphics(graphics); + GdipDisposeImage((GpImage*)metafile); + return; + } + + hbrush = CreateSolidBrush(0xff); + + holdbrush = SelectObject(metafile_dc, hbrush); + + GdiComment(metafile_dc, 8, (const BYTE*)"winetest"); + + SelectObject(metafile_dc, holdbrush); + + DeleteObject(hbrush); + + stat = GdipReleaseDC(graphics, metafile_dc); + expect(Ok, stat); + + stat = GdipDeleteGraphics(graphics); + expect(Ok, stat); + + check_metafile(metafile, gditransform_records, "gditransform metafile", dst_points, &frame, UnitPixel); + + sync_metafile(&metafile, "gditransform.emf"); + + stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap); + expect(Ok, stat); + + stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics); + expect(Ok, stat); + + play_metafile(metafile, graphics, gditransform_records, "gditransform playback", dst_points, &frame, UnitPixel); + + stat = GdipBitmapGetPixel(bitmap, 10, 10, &color); + expect(Ok, stat); + expect(0xffff0000, color); + + stat = GdipBitmapGetPixel(bitmap, 30, 30, &color); + expect(Ok, stat); + todo_wine expect(0x00000000, color); + + stat = GdipDeleteGraphics(graphics); + expect(Ok, stat); + + stat = GdipDisposeImage((GpImage*)bitmap); + expect(Ok, stat); + + stat = GdipDisposeImage((GpImage*)metafile); + expect(Ok, stat); +} + START_TEST(metafile) { struct GdiplusStartupInput gdiplusStartupInput; @@ -2181,6 +2308,7 @@ START_TEST(metafile) test_frameunit(); test_containers(); test_clipping(); + test_gditransform(); GdiplusShutdown(gdiplusToken); } -- 2.7.4 From madewokherd at gmail.com Fri Oct 7 16:03:44 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Fri, 7 Oct 2016 16:03:44 -0500 Subject: [3/3] gdiplus: Implement EMR_SETWORLDTRANSFORM playback. Message-ID: <1475874224-15291-3-git-send-email-madewokherd@gmail.com> From: Vincent Povirk Signed-off-by: Vincent Povirk --- dlls/gdiplus/gdiplus_private.h | 1 + dlls/gdiplus/metafile.c | 50 +++++++++++++++++++++++++++++------------- dlls/gdiplus/tests/metafile.c | 2 +- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 86a29a0..340e9bd 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -374,6 +374,7 @@ struct GpMetafile{ GpRectF src_rect; HANDLETABLE *handle_table; int handle_count; + XFORM gdiworldtransform; GpMatrix *world_transform; GpUnit page_unit; REAL page_scale; diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index 803384a..a3fdb34 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -1040,6 +1040,30 @@ GpStatus WINGDIPAPI GdipGetHemfFromMetafile(GpMetafile *metafile, HENHMETAFILE * return Ok; } +static GpStatus METAFILE_PlaybackUpdateGdiTransform(GpMetafile *metafile) +{ + XFORM combined, final; + const GpRectF *rect; + const GpPointF *pt; + + /* This transforms metafile device space to output points. */ + rect = &metafile->src_rect; + pt = metafile->playback_points; + final.eM11 = (pt[1].X - pt[0].X) / rect->Width; + final.eM21 = (pt[2].X - pt[0].X) / rect->Height; + final.eDx = pt[0].X - final.eM11 * rect->X - final.eM21 * rect->Y; + final.eM12 = (pt[1].Y - pt[0].Y) / rect->Width; + final.eM22 = (pt[2].Y - pt[0].Y) / rect->Height; + final.eDy = pt[0].Y - final.eM12 * rect->X - final.eM22 * rect->Y; + + CombineTransform(&combined, &metafile->gdiworldtransform, &final); + + SetGraphicsMode(metafile->playback_dc, GM_ADVANCED); + SetWorldTransform(metafile->playback_dc, &combined); + + return Ok; +} + static GpStatus METAFILE_PlaybackGetDC(GpMetafile *metafile) { GpStatus stat = Ok; @@ -1048,20 +1072,10 @@ static GpStatus METAFILE_PlaybackGetDC(GpMetafile *metafile) if (stat == Ok) { - /* The result of GdipGetDC always expects device co-ordinates, but the - * device co-ordinates of the source metafile do not correspond to - * device co-ordinates of the destination. Therefore, we set up the DC - * so that the metafile's bounds map to the destination points where we - * are drawing this metafile. */ - SetMapMode(metafile->playback_dc, MM_ANISOTROPIC); - - SetWindowOrgEx(metafile->playback_dc, metafile->bounds.X, metafile->bounds.Y, NULL); - SetWindowExtEx(metafile->playback_dc, metafile->bounds.Width, metafile->bounds.Height, NULL); - - SetViewportOrgEx(metafile->playback_dc, metafile->playback_points[0].X, metafile->playback_points[0].Y, NULL); - SetViewportExtEx(metafile->playback_dc, - metafile->playback_points[1].X - metafile->playback_points[0].X, - metafile->playback_points[2].Y - metafile->playback_points[0].Y, NULL); + static const XFORM identity = {1, 0, 0, 1, 0, 0}; + + metafile->gdiworldtransform = identity; + METAFILE_PlaybackUpdateGdiTransform(metafile); } return stat; @@ -1141,12 +1155,18 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, case EMR_SETVIEWPORTORGEX: case EMR_SETVIEWPORTEXTEX: case EMR_EXTSELECTCLIPRGN: - case EMR_SETWORLDTRANSFORM: case EMR_SCALEVIEWPORTEXTEX: case EMR_SCALEWINDOWEXTEX: case EMR_MODIFYWORLDTRANSFORM: FIXME("not implemented for record type %x\n", recordType); break; + case EMR_SETWORLDTRANSFORM: + { + const XFORM* xform = (void*)data; + real_metafile->gdiworldtransform = *xform; + METAFILE_PlaybackUpdateGdiTransform(real_metafile); + break; + } default: break; } diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c index 8531ce5..0646c7a 100644 --- a/dlls/gdiplus/tests/metafile.c +++ b/dlls/gdiplus/tests/metafile.c @@ -2260,7 +2260,7 @@ static void test_gditransform(void) stat = GdipBitmapGetPixel(bitmap, 30, 30, &color); expect(Ok, stat); - todo_wine expect(0x00000000, color); + expect(0x00000000, color); stat = GdipDeleteGraphics(graphics); expect(Ok, stat); -- 2.7.4 From nsivov at codeweavers.com Fri Oct 7 17:09:50 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Sat, 8 Oct 2016 01:09:50 +0300 Subject: [PATCH] d2d1: Support shared bitmaps created using dxgi surface Message-ID: <20161007220950.10519-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/d2d1/bitmap.c | 60 +++++++++++++++++++++++++++++++++++++++++++++-- dlls/d2d1/d2d1_private.h | 2 +- dlls/d2d1/render_target.c | 2 +- dlls/d2d1/tests/d2d1.c | 41 ++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 4 deletions(-) diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c index b2f2ad7..012d19d 100644 --- a/dlls/d2d1/bitmap.c +++ b/dlls/d2d1/bitmap.c @@ -296,13 +296,18 @@ HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE return *bitmap ? S_OK : E_OUTOFMEMORY; } -HRESULT d2d_bitmap_create_shared(ID2D1Factory *factory, ID3D10Device *target_device, +HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device *target_device, REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) { + D2D1_BITMAP_PROPERTIES d; + ID2D1Factory *factory; + + ID2D1RenderTarget_GetFactory(render_target, &factory); + ID2D1Factory_Release(factory); + if (IsEqualGUID(iid, &IID_ID2D1Bitmap)) { struct d2d_bitmap *src_impl = unsafe_impl_from_ID2D1Bitmap(data); - D2D1_BITMAP_PROPERTIES d; ID3D10Device *device; if (src_impl->factory != factory) @@ -336,6 +341,57 @@ HRESULT d2d_bitmap_create_shared(ID2D1Factory *factory, ID3D10Device *target_dev return S_OK; } + else if (IsEqualGUID(iid, &IID_IDXGISurface) || IsEqualGUID(iid, &IID_IDXGISurface1)) + { + ID3D10ShaderResourceView *view; + DXGI_SURFACE_DESC surface_desc; + IDXGISurface *surface = data; + ID3D10Resource *resource; + D2D1_SIZE_U pixel_size; + HRESULT hr; + + if (FAILED(IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource))) + { + WARN("Failed to get d3d resource from dxgi surface.\n"); + return E_FAIL; + } + + hr = ID3D10Device_CreateShaderResourceView(target_device, resource, NULL, &view); + ID3D10Resource_Release(resource); + if (FAILED(hr)) + { + WARN("Failed to create shader resource view, hr %#x.\n", hr); + return hr; + } + + if (!(*bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**bitmap)))) + { + ID3D10ShaderResourceView_Release(view); + return E_OUTOFMEMORY; + } + + d = *desc; + if (d.dpiX == 0.0f || d.dpiY == 0.0f) + { + float dpi_x, dpi_y; + + ID2D1RenderTarget_GetDpi(render_target, &dpi_x, &dpi_y); + if (d.dpiX == 0.0f) + d.dpiX = dpi_x; + if (d.dpiY == 0.0f) + d.dpiY = dpi_y; + } + + IDXGISurface_GetDesc(surface, &surface_desc); + pixel_size.width = surface_desc.Width; + pixel_size.height = surface_desc.Height; + + d2d_bitmap_init(*bitmap, factory, view, pixel_size, &d); + ID3D10ShaderResourceView_Release(view); + TRACE("Created bitmap %p.\n", *bitmap); + + return S_OK; + } WARN("Unhandled interface %s.\n", debugstr_guid(iid)); diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 6cee5ef..c5c3a03 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -236,7 +236,7 @@ struct d2d_bitmap HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; -HRESULT d2d_bitmap_create_shared(ID2D1Factory *factory, ID3D10Device *device, REFIID iid, void *data, +HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device *device, REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; HRESULT d2d_bitmap_create_from_wic_bitmap(ID2D1Factory *factory, ID3D10Device *device, IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index e9a971e..78000af 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -341,7 +341,7 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSharedBitmap(ID2D1R TRACE("iface %p, iid %s, data %p, desc %p, bitmap %p.\n", iface, debugstr_guid(iid), data, desc, bitmap); - if (SUCCEEDED(hr = d2d_bitmap_create_shared(render_target->factory, render_target->device, iid, data, desc, &object))) + if (SUCCEEDED(hr = d2d_bitmap_create_shared(iface, render_target->device, iid, data, desc, &object))) *bitmap = &object->ID2D1Bitmap_iface; return hr; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index ba4be0c..339fc52 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -2046,8 +2046,10 @@ static void test_shared_bitmap(void) ID3D10Device1 *device1, *device2; IWICImagingFactory *wic_factory; ID2D1Bitmap *bitmap1, *bitmap2; + DXGI_SURFACE_DESC surface_desc; ID2D1RenderTarget *rt1, *rt2; D2D1_SIZE_U size = {4, 4}; + IDXGISurface1 *surface3; HWND window1, window2; HRESULT hr; @@ -2171,6 +2173,45 @@ static void test_shared_bitmap(void) ID2D1Bitmap_Release(bitmap2); ID2D1RenderTarget_Release(rt2); + /* Shared DXGI surface. */ + desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + desc.dpiX = 0.0f; + desc.dpiY = 0.0f; + desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, surface2, &desc, &rt2); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + bitmap_desc.dpiX = 0.0f; + bitmap_desc.dpiY = 0.0f; + + hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface, surface2, &bitmap_desc, &bitmap2); + ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr); + + size = ID2D1Bitmap_GetPixelSize(bitmap2); + hr = IDXGISurface_GetDesc(surface2, &surface_desc); + ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr); + ok(size.width == surface_desc.Width && size.height == surface_desc.Height, "Got wrong bitmap size.\n"); + + ID2D1Bitmap_Release(bitmap2); + + /* IDXGISurface1 is supported too. */ + if (IDXGISurface_QueryInterface(surface2, &IID_IDXGISurface1, (void **)&surface3) == S_OK) + { + hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface1, surface3, &bitmap_desc, &bitmap2); + ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr); + + ID2D1Bitmap_Release(bitmap2); + IDXGISurface1_Release(surface3); + } + + ID2D1RenderTarget_Release(rt2); + ID2D1Bitmap_Release(bitmap1); ID2D1RenderTarget_Release(rt1); ID2D1Factory_Release(factory2); -- 2.9.3 From frederic.delanoy at gmail.com Sat Oct 8 10:25:41 2016 From: frederic.delanoy at gmail.com (=?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delanoy?=) Date: Sat, 8 Oct 2016 17:25:41 +0200 Subject: [website] French translation for release 1.8.5 Message-ID: <20161008152541.18208-1-frederic.delanoy@gmail.com> Signed-off-by: Frédéric Delanoy --- news/fr/2016100701.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 news/fr/2016100701.xml diff --git a/news/fr/2016100701.xml b/news/fr/2016100701.xml new file mode 100644 index 0000000..9072d16 --- /dev/null +++ b/news/fr/2016100701.xml @@ -0,0 +1,11 @@ + +7 octobre 2016 +Sortie de Wine 1.8.5 + +

La version de maintenance 1.8.5 de Wine est disponible.

+

Nouveautés de cette version : +

    +
  • Diverses corrections de bugs.
  • +
+

Le code source est disponible dès à présent. Les paquets binaires sont en cours de construction, et apparaîtront sous peu sur leurs sites de téléchargement respectifs. +

-- 2.10.1 From nsivov at codeweavers.com Sat Oct 8 12:18:00 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Sat, 8 Oct 2016 20:18:00 +0300 Subject: [v2 PATCH] d2d1: Support shared bitmaps created from dxgi surface Message-ID: <20161008171800.20686-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- v2: fixed test crash on vista dlls/d2d1/bitmap.c | 60 +++++++++++++++++++++++++++++++++++++++++++++-- dlls/d2d1/d2d1_private.h | 2 +- dlls/d2d1/render_target.c | 2 +- dlls/d2d1/tests/d2d1.c | 44 ++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 4 deletions(-) diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c index b2f2ad7..012d19d 100644 --- a/dlls/d2d1/bitmap.c +++ b/dlls/d2d1/bitmap.c @@ -296,13 +296,18 @@ HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE return *bitmap ? S_OK : E_OUTOFMEMORY; } -HRESULT d2d_bitmap_create_shared(ID2D1Factory *factory, ID3D10Device *target_device, +HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device *target_device, REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) { + D2D1_BITMAP_PROPERTIES d; + ID2D1Factory *factory; + + ID2D1RenderTarget_GetFactory(render_target, &factory); + ID2D1Factory_Release(factory); + if (IsEqualGUID(iid, &IID_ID2D1Bitmap)) { struct d2d_bitmap *src_impl = unsafe_impl_from_ID2D1Bitmap(data); - D2D1_BITMAP_PROPERTIES d; ID3D10Device *device; if (src_impl->factory != factory) @@ -336,6 +341,57 @@ HRESULT d2d_bitmap_create_shared(ID2D1Factory *factory, ID3D10Device *target_dev return S_OK; } + else if (IsEqualGUID(iid, &IID_IDXGISurface) || IsEqualGUID(iid, &IID_IDXGISurface1)) + { + ID3D10ShaderResourceView *view; + DXGI_SURFACE_DESC surface_desc; + IDXGISurface *surface = data; + ID3D10Resource *resource; + D2D1_SIZE_U pixel_size; + HRESULT hr; + + if (FAILED(IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource))) + { + WARN("Failed to get d3d resource from dxgi surface.\n"); + return E_FAIL; + } + + hr = ID3D10Device_CreateShaderResourceView(target_device, resource, NULL, &view); + ID3D10Resource_Release(resource); + if (FAILED(hr)) + { + WARN("Failed to create shader resource view, hr %#x.\n", hr); + return hr; + } + + if (!(*bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**bitmap)))) + { + ID3D10ShaderResourceView_Release(view); + return E_OUTOFMEMORY; + } + + d = *desc; + if (d.dpiX == 0.0f || d.dpiY == 0.0f) + { + float dpi_x, dpi_y; + + ID2D1RenderTarget_GetDpi(render_target, &dpi_x, &dpi_y); + if (d.dpiX == 0.0f) + d.dpiX = dpi_x; + if (d.dpiY == 0.0f) + d.dpiY = dpi_y; + } + + IDXGISurface_GetDesc(surface, &surface_desc); + pixel_size.width = surface_desc.Width; + pixel_size.height = surface_desc.Height; + + d2d_bitmap_init(*bitmap, factory, view, pixel_size, &d); + ID3D10ShaderResourceView_Release(view); + TRACE("Created bitmap %p.\n", *bitmap); + + return S_OK; + } WARN("Unhandled interface %s.\n", debugstr_guid(iid)); diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 6cee5ef..c5c3a03 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -236,7 +236,7 @@ struct d2d_bitmap HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; -HRESULT d2d_bitmap_create_shared(ID2D1Factory *factory, ID3D10Device *device, REFIID iid, void *data, +HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device *device, REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; HRESULT d2d_bitmap_create_from_wic_bitmap(ID2D1Factory *factory, ID3D10Device *device, IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index e9a971e..78000af 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -341,7 +341,7 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSharedBitmap(ID2D1R TRACE("iface %p, iid %s, data %p, desc %p, bitmap %p.\n", iface, debugstr_guid(iid), data, desc, bitmap); - if (SUCCEEDED(hr = d2d_bitmap_create_shared(render_target->factory, render_target->device, iid, data, desc, &object))) + if (SUCCEEDED(hr = d2d_bitmap_create_shared(iface, render_target->device, iid, data, desc, &object))) *bitmap = &object->ID2D1Bitmap_iface; return hr; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index ba4be0c..38012ca 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -2046,8 +2046,10 @@ static void test_shared_bitmap(void) ID3D10Device1 *device1, *device2; IWICImagingFactory *wic_factory; ID2D1Bitmap *bitmap1, *bitmap2; + DXGI_SURFACE_DESC surface_desc; ID2D1RenderTarget *rt1, *rt2; D2D1_SIZE_U size = {4, 4}; + IDXGISurface1 *surface3; HWND window1, window2; HRESULT hr; @@ -2171,6 +2173,48 @@ static void test_shared_bitmap(void) ID2D1Bitmap_Release(bitmap2); ID2D1RenderTarget_Release(rt2); + /* Shared DXGI surface. */ + desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + desc.dpiX = 0.0f; + desc.dpiY = 0.0f; + desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, surface2, &desc, &rt2); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + bitmap_desc.dpiX = 0.0f; + bitmap_desc.dpiY = 0.0f; + + hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface, surface2, &bitmap_desc, &bitmap2); + ok(SUCCEEDED(hr) || broken(hr == E_INVALIDARG) /* vista */, "Failed to create bitmap, hr %#x.\n", hr); + + if (SUCCEEDED(hr)) + { + size = ID2D1Bitmap_GetPixelSize(bitmap2); + hr = IDXGISurface_GetDesc(surface2, &surface_desc); + ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr); + ok(size.width == surface_desc.Width && size.height == surface_desc.Height, "Got wrong bitmap size.\n"); + + ID2D1Bitmap_Release(bitmap2); + + /* IDXGISurface1 is supported too. */ + if (IDXGISurface_QueryInterface(surface2, &IID_IDXGISurface1, (void **)&surface3) == S_OK) + { + hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface1, surface3, &bitmap_desc, &bitmap2); + ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr); + + ID2D1Bitmap_Release(bitmap2); + IDXGISurface1_Release(surface3); + } + } + + ID2D1RenderTarget_Release(rt2); + ID2D1Bitmap_Release(bitmap1); ID2D1RenderTarget_Release(rt1); ID2D1Factory_Release(factory2); -- 2.9.3 From aric at codeweavers.com Sat Oct 8 18:56:24 2016 From: aric at codeweavers.com (Aric Stewart) Date: Sat, 8 Oct 2016 18:56:24 -0500 Subject: [PATCH v2 1/2] winebus.sys: Implement IOCTL_HID_GET_DEVICE_DESCRIPTOR for hidraw Message-ID: <3e6c4e8c-124c-8486-98ca-1edbb10b2371@codeweavers.com> v2: Some suggestions from Sebastian Lackner Signed-off-by: Aric Stewart --- configure | 1 + configure.ac | 1 + dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_udev.c | 53 ++++++++++++++++++++++++++++++++++++++++++--- dlls/winebus.sys/main.c | 34 +++++++++++++++++++++++++++++ include/config.h.in | 3 +++ 6 files changed, 90 insertions(+), 3 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: v2-0001-winebus.sys-Implement-IOCTL_HID_GET_DEVICE_DESCRIPT.txt Type: text/x-patch Size: 6690 bytes Desc: not available URL: From aric at codeweavers.com Sat Oct 8 18:56:32 2016 From: aric at codeweavers.com (Aric Stewart) Date: Sat, 8 Oct 2016 18:56:32 -0500 Subject: [PATCH v2 2/2] winebus.sys: Implement IOCTL_HID_GET_REPORT_DESCRIPTOR for hidraw Message-ID: <28638df2-fa45-d7eb-13a5-ac6762fad5d8@codeweavers.com> v2: Suggestions from Sebastian Lackner Signed-off-by: Aric Stewart --- dlls/winebus.sys/main.c | 9 +++++++++ 1 file changed, 9 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: v2-0002-winebus.sys-Implement-IOCTL_HID_GET_REPORT_DESCRIPT.txt Type: text/x-patch Size: 840 bytes Desc: not available URL: From marcus at jet.franken.de Sun Oct 9 02:24:52 2016 From: marcus at jet.franken.de (Marcus Meissner) Date: Sun, 9 Oct 2016 09:24:52 +0200 Subject: [PATCH] gdiplus: assign error return (Coverity) Message-ID: <20161009072452.18039-1-marcus@jet.franken.de> 1373482 Logically dead code Signed-off-by: Marcus Meissner --- dlls/gdiplus/metafile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index 9de584c..f9ed14c 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -1361,7 +1361,7 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, return stat; } - GdipBeginContainer2(metafile->playback_graphics, &cont->state); + stat = GdipBeginContainer2(metafile->playback_graphics, &cont->state); if (stat != Ok) { -- 2.10.0 From marcus at jet.franken.de Sun Oct 9 02:40:57 2016 From: marcus at jet.franken.de (Marcus Meissner) Date: Sun, 9 Oct 2016 09:40:57 +0200 Subject: [PATCH] webservices: add error checking (Coverity) Message-ID: <20161009074057.21974-1-marcus@jet.franken.de> 1373480 Unchecked return value Signed-off-by: Marcus Meissner --- dlls/webservices/channel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/webservices/channel.c b/dlls/webservices/channel.c index 445d877..2b9c9d7 100644 --- a/dlls/webservices/channel.c +++ b/dlls/webservices/channel.c @@ -466,7 +466,7 @@ HRESULT WINAPI WsSendMessage( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS_MESS if (!handle || !msg || !desc) return E_INVALIDARG; - WsInitializeMessage( msg, WS_REQUEST_MESSAGE, NULL, NULL ); + if ((hr = WsInitializeMessage( msg, WS_REQUEST_MESSAGE, NULL, NULL )) != S_OK) return hr; if ((hr = WsAddressMessage( msg, &channel->addr, NULL )) != S_OK) return hr; if ((hr = message_set_action( msg, desc->action )) != S_OK) return hr; -- 2.10.0 From carlo.bramix at libero.it Sun Oct 9 06:05:19 2016 From: carlo.bramix at libero.it (Carlo Bramini) Date: Sun, 9 Oct 2016 13:05:19 +0200 (CEST) Subject: [PATCH] winefile: use StrFormatByteSizeW Message-ID: <536078922.837341476011119904.JavaMail.httpd@webmail-51.iol.local> Attached patch removes hand-written code and call StrFormatByteSizeW(), which does the same identical job. Sincerely. Signed-off-by: Carlo Bramini -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: winefile.txt URL: From lukasz.wojnilowicz at gmail.com Sat Oct 8 00:40:13 2016 From: lukasz.wojnilowicz at gmail.com (=?UTF-8?q?=C5=81ukasz=20Wojni=C5=82owicz?=) Date: Sat, 8 Oct 2016 07:40:13 +0200 Subject: [website] Polish translation for release 1.9.20 Message-ID: <1475905214-6807-1-git-send-email-lukasz.wojnilowicz@gmail.com> --- news/pl/2016100101.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 news/pl/2016100101.xml diff --git a/news/pl/2016100101.xml b/news/pl/2016100101.xml new file mode 100644 index 0000000..2a3f3a6 --- /dev/null +++ b/news/pl/2016100101.xml @@ -0,0 +1,15 @@ + +Październik 1, 2016 +Wydano Wine 1.9.20 + +

Wydanie rozwojowe Wine 1.9.20 jest już dostępne.

+

Co nowego w tym wydaniu: +

    +
  • Reimplementacja API schowka.
  • +
  • Obsługa wiadomości w UsługachSiecowych.
  • +
  • Dużo więcej API dla bibliotek Set.
  • +
  • Rozmaite poprawki błędów.
  • +
+

Źródło jest już dostępne. +Paczki binarne są w trakcie budowy i ukażą się wkrótce w przeznaczonych dla nich pobieralniach. +

-- 2.7.4 From lukasz.wojnilowicz at gmail.com Sat Oct 8 00:40:14 2016 From: lukasz.wojnilowicz at gmail.com (=?UTF-8?q?=C5=81ukasz=20Wojni=C5=82owicz?=) Date: Sat, 8 Oct 2016 07:40:14 +0200 Subject: [website] Polish translation for release 1.8.5 In-Reply-To: <1475905214-6807-1-git-send-email-lukasz.wojnilowicz@gmail.com> References: <1475905214-6807-1-git-send-email-lukasz.wojnilowicz@gmail.com> Message-ID: <1475905214-6807-2-git-send-email-lukasz.wojnilowicz@gmail.com> --- news/pl/2016100701.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 news/pl/2016100701.xml diff --git a/news/pl/2016100701.xml b/news/pl/2016100701.xml new file mode 100644 index 0000000..624ca9e --- /dev/null +++ b/news/pl/2016100701.xml @@ -0,0 +1,12 @@ + +Październik 7, 2016 +Wydano Wine 1.8.5 + +

Poprawione wydanie Wine 1.8.5 jest już dostępne.

+

Co nowego w tym wydaniu: +

    +
  • Rozmaite poprawki błędów.
  • +
+

Źródło jest już dostępne. +Paczki binarne są w trakcie budowy i ukażą się wkrótce w przeznaczonych dla nich pobieralniach. +

-- 2.7.4 From gerald at pfeifer.com Sat Oct 8 15:31:15 2016 From: gerald at pfeifer.com (Gerald Pfeifer) Date: Sat, 8 Oct 2016 22:31:15 +0200 (CEST) Subject: kernel32: Avoid two potential buffer overflows of cStr in create_hardware_branch. Message-ID: In create_hardware_branch() we have a buffer of char[40], but then use sprintf to fill this that can exceed those 40 characters by using a format specifier of "/proc/ide/%s/media" and struct dirent.d_name for the parameter. GCC 7 will diagnose this. Signed-off-by: Gerald Pfeifer --- dlls/kernel32/oldconfig.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dlls/kernel32/oldconfig.c b/dlls/kernel32/oldconfig.c index 6c80dc6..b7f77bf 100644 --- a/dlls/kernel32/oldconfig.c +++ b/dlls/kernel32/oldconfig.c @@ -275,7 +275,9 @@ static void create_hardware_branch(void) DIR *idedir; struct dirent *dent = NULL; FILE *procfile = NULL; - char cStr[40], cDevModel[40], cUnixDeviceName[40], read1[10] = "\0", read2[10] = "\0"; + char cStr[sizeof(dent->d_name)+sizeof(procname_ide_media)], + cDevModel[40], cUnixDeviceName[40], + read1[10] = "\0", read2[10] = "\0"; SCSI_ADDRESS scsi_addr; UINT nType; struct LinuxProcScsiDevice dev; -- 2.9.2 From sebastian at fds-team.de Sun Oct 9 11:56:29 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Sun, 9 Oct 2016 18:56:29 +0200 Subject: libwine: Add public symbol to access list of debug options. Message-ID: <8bf24267-4514-5e33-e14f-d2e44b6e6380@fds-team.de> Signed-off-by: Sebastian Lackner --- Fixes https://bugs.winehq.org/show_bug.cgi?id=41457. Currently, the "edit debug channels" feature of taskmgr is broken in release builds, because: * "debug_options" is not exported as a public symbol * taskmgr passes SYMOPT_PUBLICS_ONLY to SymSetOptions This combination does not make any sense (not even installing debug packages is sufficient). This patch replaces debug_options with __wine_dbg_options and makes it a public symbol. libs/wine/debug.c | 24 ++++++++++++------------ libs/wine/wine.def | 1 + libs/wine/wine.map | 1 + programs/taskmgr/dbgchnl.c | 2 +- programs/winedbg/info.c | 2 +- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/libs/wine/debug.c b/libs/wine/debug.c index 8b04ef9..b26dd52 100644 --- a/libs/wine/debug.c +++ b/libs/wine/debug.c @@ -44,7 +44,7 @@ static const char * const debug_classes[] = { "fixme", "err", "warn", "trace" }; static unsigned char default_flags = (1 << __WINE_DBCL_ERR) | (1 << __WINE_DBCL_FIXME); static int nb_debug_options = -1; -static struct __wine_debug_channel debug_options[MAX_DEBUG_OPTIONS]; +struct __wine_debug_channel __wine_dbg_options[MAX_DEBUG_OPTIONS]; static struct __wine_debug_functions funcs; @@ -64,8 +64,8 @@ unsigned char __wine_dbg_get_channel_flags( struct __wine_debug_channel *channel if (nb_debug_options) { - struct __wine_debug_channel *opt = bsearch( channel->name, debug_options, nb_debug_options, - sizeof(debug_options[0]), cmp_name ); + struct __wine_debug_channel *opt = bsearch( channel->name, __wine_dbg_options, nb_debug_options, + sizeof(__wine_dbg_options[0]), cmp_name ); if (opt) return opt->flags; } /* no option for this channel */ @@ -81,8 +81,8 @@ int __wine_dbg_set_channel_flags( struct __wine_debug_channel *channel, if (nb_debug_options) { - struct __wine_debug_channel *opt = bsearch( channel->name, debug_options, nb_debug_options, - sizeof(debug_options[0]), cmp_name ); + struct __wine_debug_channel *opt = bsearch( channel->name, __wine_dbg_options, nb_debug_options, + sizeof(__wine_dbg_options[0]), cmp_name ); if (opt) { opt->flags = (opt->flags & ~clear) | set; @@ -102,15 +102,15 @@ static void add_option( const char *name, unsigned char set, unsigned char clear default_flags = (default_flags & ~clear) | set; return; } - if (strlen(name) >= sizeof(debug_options[0].name)) return; + if (strlen(name) >= sizeof(__wine_dbg_options[0].name)) return; while (min <= max) { pos = (min + max) / 2; - res = strcmp( name, debug_options[pos].name ); + res = strcmp( name, __wine_dbg_options[pos].name ); if (!res) { - debug_options[pos].flags = (debug_options[pos].flags & ~clear) | set; + __wine_dbg_options[pos].flags = (__wine_dbg_options[pos].flags & ~clear) | set; return; } if (res < 0) max = pos - 1; @@ -119,10 +119,10 @@ static void add_option( const char *name, unsigned char set, unsigned char clear if (nb_debug_options >= MAX_DEBUG_OPTIONS) return; pos = min; - if (pos < nb_debug_options) memmove( &debug_options[pos + 1], &debug_options[pos], - (nb_debug_options - pos) * sizeof(debug_options[0]) ); - strcpy( debug_options[pos].name, name ); - debug_options[pos].flags = (default_flags & ~clear) | set; + if (pos < nb_debug_options) memmove( &__wine_dbg_options[pos + 1], &__wine_dbg_options[pos], + (nb_debug_options - pos) * sizeof(__wine_dbg_options[0]) ); + strcpy( __wine_dbg_options[pos].name, name ); + __wine_dbg_options[pos].flags = (default_flags & ~clear) | set; nb_debug_options++; } diff --git a/libs/wine/wine.def b/libs/wine/wine.def index ed315bd..c08c83b 100644 --- a/libs/wine/wine.def +++ b/libs/wine/wine.def @@ -2,6 +2,7 @@ LIBRARY libwine.dll EXPORTS __wine_dbg_get_channel_flags + __wine_dbg_options __wine_dbg_set_channel_flags __wine_dbg_set_functions __wine_dll_register diff --git a/libs/wine/wine.map b/libs/wine/wine.map index 2159fac..f44c66f 100644 --- a/libs/wine/wine.map +++ b/libs/wine/wine.map @@ -2,6 +2,7 @@ WINE_1.0 { global: __wine_dbg_get_channel_flags; + __wine_dbg_options; __wine_dbg_set_channel_flags; __wine_dbg_set_functions; __wine_dll_register; diff --git a/programs/taskmgr/dbgchnl.c b/programs/taskmgr/dbgchnl.c index 6e2dea0..da9a078 100644 --- a/programs/taskmgr/dbgchnl.c +++ b/programs/taskmgr/dbgchnl.c @@ -196,7 +196,7 @@ static int enum_channel(HANDLE hProcess, EnumChannelCB ce, void* user) int ret = 1; void* addr; - if (!(addr = get_symbol(hProcess, "libwine.so.1!debug_options"))) return -1; + if (!(addr = get_symbol(hProcess, "libwine.so.1!__wine_dbg_options"))) return -1; while (ret && addr && ReadProcessMemory(hProcess, addr, &channel, sizeof(channel), NULL)) { diff --git a/programs/winedbg/info.c b/programs/winedbg/info.c index e521252..33c7873 100644 --- a/programs/winedbg/info.c +++ b/programs/winedbg/info.c @@ -796,7 +796,7 @@ void info_wine_dbg_channel(BOOL turn_on, const char* cls, const char* name) return; } - if (symbol_get_lvalue("debug_options", -1, &lvalue, FALSE) != sglv_found) + if (symbol_get_lvalue("__wine_dbg_options", -1, &lvalue, FALSE) != sglv_found) { return; } -- 2.9.0 From nsivov at codeweavers.com Sun Oct 9 15:35:59 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Sun, 9 Oct 2016 23:35:59 +0300 Subject: [PATCH] include: Update to latest dwrite revision Message-ID: <20161009203559.3500-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- include/d2dbasetypes.h | 12 ------ include/dcommon.h | 14 +++++++ include/dwrite_3.idl | 101 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 12 deletions(-) diff --git a/include/d2dbasetypes.h b/include/d2dbasetypes.h index e5acff2..b231081 100644 --- a/include/d2dbasetypes.h +++ b/include/d2dbasetypes.h @@ -29,12 +29,6 @@ typedef struct D3DCOLORVALUE typedef D3DCOLORVALUE D2D_COLOR_F; -typedef struct D2D_POINT_2F -{ - FLOAT x; - FLOAT y; -} D2D_POINT_2F; - typedef struct D2D_MATRIX_3X2_F { float _11; @@ -59,12 +53,6 @@ typedef struct D2D_SIZE_F float height; } D2D_SIZE_F; -typedef struct D2D_SIZE_U -{ - UINT32 width; - UINT32 height; -} D2D_SIZE_U; - typedef struct D2D_POINT_2U { UINT32 x; diff --git a/include/dcommon.h b/include/dcommon.h index 56445a3..a516e8a 100644 --- a/include/dcommon.h +++ b/include/dcommon.h @@ -43,4 +43,18 @@ typedef struct D2D1_PIXEL_FORMAT D2D1_ALPHA_MODE alphaMode; } D2D1_PIXEL_FORMAT; +typedef struct D2D_POINT_2F +{ + FLOAT x; + FLOAT y; +} D2D_POINT_2F, D2D1_POINT_2F; + +typedef POINT D2D_POINT_2L, D2D1_POINT_2L; + +typedef struct D2D_SIZE_U +{ + UINT32 width; + UINT32 height; +} D2D_SIZE_U, D2D1_SIZE_U; + #endif /* __WINE_DCOMMON_H */ diff --git a/include/dwrite_3.idl b/include/dwrite_3.idl index 9e7a4c6..afe7e84 100644 --- a/include/dwrite_3.idl +++ b/include/dwrite_3.idl @@ -397,3 +397,104 @@ interface IDWriteFactory3 : IDWriteFactory2 HRESULT GetFontDownloadQueue(IDWriteFontDownloadQueue **queue); } + +typedef enum DWRITE_GLYPH_IMAGE_FORMATS +{ + DWRITE_GLYPH_IMAGE_FORMATS_NONE = 0, + DWRITE_GLYPH_IMAGE_FORMATS_TRUETYPE = 1 << 0, + DWRITE_GLYPH_IMAGE_FORMATS_CFF = 1 << 1, + DWRITE_GLYPH_IMAGE_FORMATS_COLR = 1 << 2, + DWRITE_GLYPH_IMAGE_FORMATS_SVG = 1 << 3, + DWRITE_GLYPH_IMAGE_FORMATS_PNG = 1 << 4, + DWRITE_GLYPH_IMAGE_FORMATS_JPEG = 1 << 5, + DWRITE_GLYPH_IMAGE_FORMATS_TIFF = 1 << 6, + DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8 = 1 << 7 +} DWRITE_GLYPH_IMAGE_FORMATS; + +typedef struct DWRITE_GLYPH_IMAGE_DATA +{ + void const *imageData; + UINT32 imageDataSize; + UINT32 uniqueDataId; + UINT32 pixelsPerEm; + D2D1_SIZE_U pixelSize; + D2D1_POINT_2L horizontalLeftOrigin; + D2D1_POINT_2L horizontalRightOrigin; + D2D1_POINT_2L verticalTopOrigin; + D2D1_POINT_2L verticalBottomOrigin; +} DWRITE_GLYPH_IMAGE_DATA; + +[ + local, + object, + uuid(27f2a904-4eb8-441d-9678-0563f53e3e2f) +] +interface IDWriteFontFace4 : IDWriteFontFace3 +{ + HRESULT GetGlyphImageFormats_( + UINT16 glyph, + UINT32 ppem_first, + UINT32 ppem_last, + DWRITE_GLYPH_IMAGE_FORMATS *formats); + DWRITE_GLYPH_IMAGE_FORMATS GetGlyphImageFormats(); + HRESULT GetGlyphImageData( + UINT16 glyph, + UINT32 ppem, + DWRITE_GLYPH_IMAGE_FORMATS format, + DWRITE_GLYPH_IMAGE_DATA *data, + void **context); + void ReleaseGlyphImageData(void *context); +} + +typedef struct DWRITE_COLOR_GLYPH_RUN1 +{ + DWRITE_GLYPH_RUN glyphRun; + DWRITE_GLYPH_RUN_DESCRIPTION *glyphRunDescription; + FLOAT baselineOriginX; + FLOAT baselineOriginY; + DWRITE_COLOR_F runColor; + UINT16 paletteIndex; + DWRITE_GLYPH_IMAGE_FORMATS glyphImageFormat; + DWRITE_MEASURING_MODE measuringMode; +} DWRITE_COLOR_GLYPH_RUN1; + +[ + local, + object, + uuid(7c5f86da-c7a1-4f05-b8e1-55a179fe5a35) +] +interface IDWriteColorGlyphRunEnumerator1 : IDWriteColorGlyphRunEnumerator +{ + HRESULT GetCurrentRun( + DWRITE_COLOR_GLYPH_RUN1 const **run); +} + +[ + local, + object, + uuid(4b0b5bd3-0797-4549-8ac5-fe915cc53856) +] +interface IDWriteFactory4 : IDWriteFactory3 +{ + HRESULT TranslateColorGlyphRun( + D2D1_POINT_2F baseline_origin, + DWRITE_GLYPH_RUN const *run, + DWRITE_GLYPH_RUN_DESCRIPTION const *run_desc, + DWRITE_GLYPH_IMAGE_FORMATS desired_formats, + DWRITE_MEASURING_MODE measuring_mode, + DWRITE_MATRIX const *transform, + UINT32 palette, + IDWriteColorGlyphRunEnumerator1 **layers); + + HRESULT ComputeGlyphOrigins_( + DWRITE_GLYPH_RUN const *run, + D2D1_POINT_2F baseline_origin, + D2D1_POINT_2F *origins); + + HRESULT ComputeGlyphOrigins( + DWRITE_GLYPH_RUN const *run, + DWRITE_MEASURING_MODE measuring_mode, + D2D1_POINT_2F baseline_origin, + DWRITE_MATRIX const *transform, + D2D1_POINT_2F *origins); +} -- 2.9.3 From kimmo.myllyvirta at gmail.com Mon Oct 10 01:36:44 2016 From: kimmo.myllyvirta at gmail.com (Kimmo Myllyvirta) Date: Mon, 10 Oct 2016 09:36:44 +0300 Subject: wined3d: Clear texture flag from correct format when color fixup is not supported. Message-ID: Looks like a copy & paste mishap. -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-wined3d-Clear-texture-flag-from-correct-format-when-.patch Type: text/x-patch Size: 1087 bytes Desc: not available URL: From hans at codeweavers.com Mon Oct 10 03:02:26 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Mon, 10 Oct 2016 10:02:26 +0200 Subject: [PATCH] webservices: add error checking (Coverity) In-Reply-To: <20161009074057.21974-1-marcus@jet.franken.de> References: <20161009074057.21974-1-marcus@jet.franken.de> Message-ID: <1476086546.6573.239.camel@codeweavers.com> Signed-off-by: Hans Leidekker From jkucia at codeweavers.com Mon Oct 10 03:22:33 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 10 Oct 2016 10:22:33 +0200 Subject: [PATCH 1/5] wined3d: Get wined3d creation flags from d3d_info. Message-ID: <1476087757-15035-1-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/glsl_shader.c | 6 +++--- dlls/wined3d/state.c | 4 ++-- dlls/wined3d/utils.c | 2 +- dlls/wined3d/wined3d_private.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 3d5e03f..4d9d9e7 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1160,7 +1160,7 @@ static void shader_glsl_ffp_vertex_normalmatrix_uniform(const struct wined3d_con return; get_modelview_matrix(context, state, 0, &mv); - if (context->device->wined3d->flags & WINED3D_LEGACY_FFP_LIGHTING) + if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING) invert_matrix_3d(&mv, &mv); else invert_matrix(&mv, &mv); @@ -2203,7 +2203,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont { if (gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) { - if (shader->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) + if (context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) shader_addline(buffer, "layout(%spixel_center_integer) in vec4 gl_FragCoord;\n", ps_args->render_offscreen ? "" : "origin_upper_left, "); else if (!ps_args->render_offscreen) @@ -5948,7 +5948,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context { if (gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]) shader_addline(buffer, "vpos = gl_FragCoord;\n"); - else if (shader->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) + else if (context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) shader_addline(buffer, "vpos = floor(vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1));\n"); else diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 71f47d6..9c1ddb0 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1712,7 +1712,7 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3 gl_info->gl_ops.gl.p_glEnable(GL_POLYGON_OFFSET_FILL); checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)"); - if (context->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS) + if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_DEPTH_BIAS) { float bias = -(float)const_bias.d; gl_info->gl_ops.gl.p_glPolygonOffset(bias, bias); @@ -4655,7 +4655,7 @@ static void viewport_miscpart_cc(struct wined3d_context *context, const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; /* See get_projection_matrix() in utils.c for a discussion about those * values. */ - float pixel_center_offset = context->device->wined3d->flags + float pixel_center_offset = context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER ? 63.0f / 128.0f : -1.0f / 128.0f; const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_viewport vp = state->viewport; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 8e83040..22d1ed9 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -4513,7 +4513,7 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w * driver, but small enough to prevent it from interfering with any * anti-aliasing. */ - if (!clip_control && context->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) + if (!clip_control && context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) center_offset = 63.0f / 64.0f; else center_offset = -1.0f / 64.0f; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 3887f91..45701cc 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3524,7 +3524,7 @@ static inline void shader_get_position_fixup(const struct wined3d_context *conte { float center_offset; - if (context->device->wined3d->flags & WINED3D_PIXEL_CENTER_INTEGER) + if (context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER) center_offset = 63.0f / 64.0f; else center_offset = -1.0f / 64.0f; -- 2.7.3 From jkucia at codeweavers.com Mon Oct 10 03:22:34 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 10 Oct 2016 10:22:34 +0200 Subject: [PATCH 2/5] wined3d: Call GL functions through gl_info.gl_ops in ffp_blit_blit_surface(). In-Reply-To: <1476087757-15035-1-git-send-email-jkucia@codeweavers.com> References: <1476087757-15035-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476087757-15035-2-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/surface.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 522874b..d44d0ba 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -3266,6 +3266,7 @@ static void ffp_blit_blit_surface(struct wined3d_device *device, enum wined3d_bl unsigned int dst_sub_resource_idx = surface_get_sub_resource_idx(dst_surface); struct wined3d_texture *dst_texture = dst_surface->container; struct wined3d_texture *src_texture = src_surface->container; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; /* Blit from offscreen surface to render target */ @@ -3277,15 +3278,16 @@ static void ffp_blit_blit_surface(struct wined3d_device *device, enum wined3d_bl wined3d_texture_set_color_key(src_texture, WINED3D_CKEY_SRC_BLT, color_key); context = context_acquire(device, dst_surface); + gl_info = context->gl_info; if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST) - glEnable(GL_ALPHA_TEST); + gl_info->gl_ops.gl.p_glEnable(GL_ALPHA_TEST); surface_blt_to_drawable(device, context, filter, !!color_key, src_surface, src_rect, dst_surface, dst_rect); if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST) - glDisable(GL_ALPHA_TEST); + gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST); context_release(context); -- 2.7.3 From jkucia at codeweavers.com Mon Oct 10 03:22:35 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 10 Oct 2016 10:22:35 +0200 Subject: [PATCH 3/5] wined3d: Call glGetIntegerv() through gl_info.gl_ops. In-Reply-To: <1476087757-15035-1-git-send-email-jkucia@codeweavers.com> References: <1476087757-15035-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476087757-15035-3-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/directx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 98b05c1..6cd8535 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2546,7 +2546,7 @@ static void enumerate_gl_extensions(struct wined3d_gl_info *gl_info, unsigned int i, j; GLint extensions_count; - glGetIntegerv(GL_NUM_EXTENSIONS, &extensions_count); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_NUM_EXTENSIONS, &extensions_count); for (i = 0; i < extensions_count; ++i) { gl_extension_name = (const char *)GL_EXTCALL(glGetStringi(GL_EXTENSIONS, i)); -- 2.7.3 From jkucia at codeweavers.com Mon Oct 10 03:22:36 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 10 Oct 2016 10:22:36 +0200 Subject: [PATCH 4/5] wined3d: Call glFlush() through gl_info.gl_ops. In-Reply-To: <1476087757-15035-1-git-send-email-jkucia@codeweavers.com> References: <1476087757-15035-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476087757-15035-4-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/context.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 98516f8..25a3ac6 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1296,8 +1296,9 @@ BOOL context_set_current(struct wined3d_context *ctx) { if (wglGetCurrentContext()) { + const struct wined3d_gl_info *gl_info = old->gl_info; TRACE("Flushing context %p before switching to %p.\n", old, ctx); - glFlush(); + gl_info->gl_ops.gl.p_glFlush(); } old->current = 0; } @@ -1316,7 +1317,7 @@ BOOL context_set_current(struct wined3d_context *ctx) return FALSE; ctx->current = 1; } - else if(wglGetCurrentContext()) + else if (wglGetCurrentContext()) { TRACE("Clearing current D3D context.\n"); if (!wglMakeCurrent(NULL, NULL)) -- 2.7.3 From jkucia at codeweavers.com Mon Oct 10 03:22:37 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 10 Oct 2016 10:22:37 +0200 Subject: [PATCH 5/5] wined3d: Call GL functions through gl_info.gl_ops in context_dump_fbo_attachment(). In-Reply-To: <1476087757-15035-1-git-send-email-jkucia@codeweavers.com> References: <1476087757-15035-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476087757-15035-5-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/context.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 25a3ac6..87d417c 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -266,10 +266,10 @@ static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, G { gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &old_texture); - glBindTexture(GL_TEXTURE_CUBE_MAP, name); - glGetTexLevelParameteriv(face, level, GL_TEXTURE_INTERNAL_FORMAT, &fmt); - glGetTexLevelParameteriv(face, level, GL_TEXTURE_WIDTH, &width); - glGetTexLevelParameteriv(face, level, GL_TEXTURE_HEIGHT, &height); + gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, name); + gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(face, level, GL_TEXTURE_INTERNAL_FORMAT, &fmt); + gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(face, level, GL_TEXTURE_WIDTH, &width); + gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(face, level, GL_TEXTURE_HEIGHT, &height); tex_target = GL_TEXTURE_CUBE_MAP; tex_type_str = "cube"; @@ -287,14 +287,14 @@ static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, G gl_info->gl_ops.gl.p_glGetIntegerv(texture_type[i].binding, &old_texture); while (gl_info->gl_ops.gl.p_glGetError()); - glBindTexture(texture_type[i].target, name); + gl_info->gl_ops.gl.p_glBindTexture(texture_type[i].target, name); if (!gl_info->gl_ops.gl.p_glGetError()) { tex_target = texture_type[i].target; tex_type_str = texture_type[i].str; break; } - glBindTexture(texture_type[i].target, old_texture); + gl_info->gl_ops.gl.p_glBindTexture(texture_type[i].target, old_texture); } if (!tex_type_str) { @@ -302,15 +302,15 @@ static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, G return; } - glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_INTERNAL_FORMAT, &fmt); - glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_WIDTH, &width); - glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_HEIGHT, &height); + gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_INTERNAL_FORMAT, &fmt); + gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_WIDTH, &width); + gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(tex_target, level, GL_TEXTURE_HEIGHT, &height); } FIXME(" %s: %s texture %d, %dx%d, format %#x.\n", debug_fboattachment(attachment), tex_type_str, name, width, height, fmt); - glBindTexture(tex_target, old_texture); + gl_info->gl_ops.gl.p_glBindTexture(tex_target, old_texture); checkGLcall("Guess texture type"); } else if (type == GL_NONE) -- 2.7.3 From hverbeet at codeweavers.com Mon Oct 10 06:26:18 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 10 Oct 2016 13:26:18 +0200 Subject: wined3d: Add missing '\n' to FIXME() messages. (v2) In-Reply-To: References: Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 10 06:26:19 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 10 Oct 2016 13:26:19 +0200 Subject: wined3d: Clear texture flag from correct format when color fixup is not supported. In-Reply-To: References: Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 10 06:26:20 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 10 Oct 2016 13:26:20 +0200 Subject: [PATCH 1/5] wined3d: Get wined3d creation flags from d3d_info. In-Reply-To: <1476087757-15035-1-git-send-email-jkucia@codeweavers.com> References: <1476087757-15035-1-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 10 06:26:21 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 10 Oct 2016 13:26:21 +0200 Subject: [PATCH 2/5] wined3d: Call GL functions through gl_info.gl_ops in ffp_blit_blit_surface(). In-Reply-To: <1476087757-15035-2-git-send-email-jkucia@codeweavers.com> References: <1476087757-15035-2-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 10 06:26:22 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 10 Oct 2016 13:26:22 +0200 Subject: [PATCH 3/5] wined3d: Call glGetIntegerv() through gl_info.gl_ops. In-Reply-To: <1476087757-15035-3-git-send-email-jkucia@codeweavers.com> References: <1476087757-15035-3-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 10 06:26:23 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 10 Oct 2016 13:26:23 +0200 Subject: [PATCH 4/5] wined3d: Call glFlush() through gl_info.gl_ops. In-Reply-To: <1476087757-15035-4-git-send-email-jkucia@codeweavers.com> References: <1476087757-15035-4-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 10 06:26:24 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 10 Oct 2016 13:26:24 +0200 Subject: [PATCH 5/5] wined3d: Call GL functions through gl_info.gl_ops in context_dump_fbo_attachment(). In-Reply-To: <1476087757-15035-5-git-send-email-jkucia@codeweavers.com> References: <1476087757-15035-5-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From huw at codeweavers.com Mon Oct 10 07:13:03 2016 From: huw at codeweavers.com (Huw Davies) Date: Mon, 10 Oct 2016 13:13:03 +0100 Subject: [PATCH 2/4] riched20: Add support for letter labelled lists. Message-ID: <1476101585-53773-2-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/para.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index ffd0a1d..b762df7 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -155,13 +155,46 @@ static ME_String *para_num_get_str( ME_Paragraph *para, WORD num ) ME_String *str = ME_MakeStringEmpty( 5 + 2 ); WCHAR *p = str->szData; static const WCHAR fmtW[] = {'%', 'd', 0}; + static const WORD letter_base[] = { 1, 26, 26 * 26, 26 * 26 * 26 }; + int i, len; + WORD letter, total, char_offset = 0; if (!str) return NULL; if ((para->fmt.wNumberingStyle & 0xf00) == PFNS_PARENS) *p++ = '('; - p += sprintfW( p, fmtW, num ); + switch (para->fmt.wNumbering) + { + case PFN_ARABIC: + default: + p += sprintfW( p, fmtW, num ); + break; + + case PFN_LCLETTER: + char_offset = 'a' - 'A'; + /* fall through */ + case PFN_UCLETTER: + if (!num) num = 1; + + /* This is not base-26 (or 27) as zeros don't count unless they are leading zeros. + It's simplest to start with the least significant letter, so first calculate how many letters are needed. */ + for (i = 0, total = 0; i < sizeof(letter_base) / sizeof(letter_base[0]); i++) + { + total += letter_base[i]; + if (num < total) break; + } + len = i; + for (i = 0; i < len; i++) + { + num -= letter_base[i]; + letter = (num / letter_base[i]) % 26; + p[len - i - 1] = letter + 'A' + char_offset; + } + p += len; + *p = 0; + break; + } switch (para->fmt.wNumberingStyle & 0xf00) { -- 2.8.2 From huw at codeweavers.com Mon Oct 10 07:13:02 2016 From: huw at codeweavers.com (Huw Davies) Date: Mon, 10 Oct 2016 13:13:02 +0100 Subject: [PATCH 1/4] riched20: Add support for arabic number labelled lists. Message-ID: <1476101585-53773-1-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/editor.h | 1 + dlls/riched20/para.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++--- dlls/riched20/string.c | 6 +-- 3 files changed, 100 insertions(+), 9 deletions(-) diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index 7d46692..237036c 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -101,6 +101,7 @@ void ME_DumpDocument(ME_TextBuffer *buffer) DECLSPEC_HIDDEN; ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars) DECLSPEC_HIDDEN; ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars) DECLSPEC_HIDDEN; ME_String *ME_MakeStringConst(const WCHAR *str, int len) DECLSPEC_HIDDEN; +ME_String *ME_MakeStringEmpty(int len) DECLSPEC_HIDDEN; void ME_DestroyString(ME_String *s) DECLSPEC_HIDDEN; BOOL ME_AppendString(ME_String *s, const WCHAR *append, int len) DECLSPEC_HIDDEN; ME_String *ME_VSplitString(ME_String *orig, int nVPos) DECLSPEC_HIDDEN; diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index 3c62da2..ffd0a1d 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -128,6 +128,59 @@ static void ME_UpdateTableFlags(ME_DisplayItem *para) para->member.para.fmt.wEffects &= ~PFE_TABLE; } +static inline BOOL para_num_same_list( const PARAFORMAT2 *item, const PARAFORMAT2 *base ) +{ + return item->wNumbering == base->wNumbering && + item->wNumberingStart == base->wNumberingStart && + item->wNumberingStyle == base->wNumberingStyle && + !(item->wNumberingStyle & PFNS_NEWNUMBER); +} + +static int para_num_get_num( ME_Paragraph *para ) +{ + ME_DisplayItem *prev; + int num = para->fmt.wNumberingStart; + + for (prev = para->prev_para; prev->type == diParagraph; + para = &prev->member.para, prev = prev->member.para.prev_para, num++) + { + if (!para_num_same_list( &prev->member.para.fmt, ¶->fmt )) break; + } + return num; +} + +static ME_String *para_num_get_str( ME_Paragraph *para, WORD num ) +{ + /* max 5 digits + '(' + ')' */ + ME_String *str = ME_MakeStringEmpty( 5 + 2 ); + WCHAR *p = str->szData; + static const WCHAR fmtW[] = {'%', 'd', 0}; + + if (!str) return NULL; + + if ((para->fmt.wNumberingStyle & 0xf00) == PFNS_PARENS) + *p++ = '('; + + p += sprintfW( p, fmtW, num ); + + switch (para->fmt.wNumberingStyle & 0xf00) + { + case PFNS_PARENS: + case PFNS_PAREN: + *p++ = ')'; + *p = 0; + break; + + case PFNS_PERIOD: + *p++ = '.'; + *p = 0; + break; + } + + str->nLen = p - str->szData; + return str; +} + void para_num_init( ME_Context *c, ME_Paragraph *para ) { ME_Style *style; @@ -144,18 +197,28 @@ void para_num_init( ME_Context *c, ME_Paragraph *para ) { style = para->eop_run->style; - cf.cbSize = sizeof(cf); - cf.dwMask = CFM_FACE | CFM_CHARSET; - memcpy( cf.szFaceName, bullet_font, sizeof(bullet_font) ); - cf.bCharSet = SYMBOL_CHARSET; - style = ME_ApplyStyle( c->editor, style, &cf ); + if (para->fmt.wNumbering == PFN_BULLET) + { + cf.cbSize = sizeof(cf); + cf.dwMask = CFM_FACE | CFM_CHARSET; + memcpy( cf.szFaceName, bullet_font, sizeof(bullet_font) ); + cf.bCharSet = SYMBOL_CHARSET; + style = ME_ApplyStyle( c->editor, style, &cf ); + } + else + { + ME_AddRefStyle( style ); + } para->para_num.style = style; } if (!para->para_num.text) { - para->para_num.text = ME_MakeStringConst( bullet_str, 1 ); + if (para->fmt.wNumbering != PFN_BULLET) + para->para_num.text = para_num_get_str( para, para_num_get_num( para ) ); + else + para->para_num.text = ME_MakeStringConst( bullet_str, 1 ); } old_font = ME_SelectStyleFont( c, para->para_num.style ); @@ -177,6 +240,17 @@ void para_num_clear( struct para_num *pn ) pn->text = NULL; } +static void para_num_clear_list( ME_Paragraph *para, const PARAFORMAT2 *orig_fmt ) +{ + do + { + para->nFlags |= MEPF_REWRAP; + para_num_clear( ¶->para_num ); + if (para->next_para->type != diParagraph) break; + para = ¶->next_para->member.para; + } while (para_num_same_list( ¶->fmt, orig_fmt )); +} + static BOOL ME_SetParaFormat(ME_TextEditor *editor, ME_Paragraph *para, const PARAFORMAT2 *pFmt) { PARAFORMAT2 copy; @@ -244,7 +318,15 @@ static BOOL ME_SetParaFormat(ME_TextEditor *editor, ME_Paragraph *para, const PA #undef COPY_FIELD if (memcmp(©, ¶->fmt, sizeof(PARAFORMAT2))) + { para->nFlags |= MEPF_REWRAP; + if (((dwMask & PFM_NUMBERING) && (copy.wNumbering != para->fmt.wNumbering)) || + ((dwMask & PFM_NUMBERINGSTART) && (copy.wNumberingStart != para->fmt.wNumberingStart)) || + ((dwMask & PFM_NUMBERINGSTYLE) && (copy.wNumberingStyle != para->fmt.wNumberingStyle))) + { + para_num_clear_list( para, © ); + } + } return TRUE; } @@ -277,6 +359,10 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, run_para = ME_GetParagraph(run); assert(run_para->member.para.fmt.cbSize == sizeof(PARAFORMAT2)); + /* Clear any cached para numbering following this paragraph */ + if (run_para->member.para.fmt.wNumbering) + para_num_clear_list( &run_para->member.para, &run_para->member.para.fmt ); + new_para->member.para.text = ME_VSplitString( run_para->member.para.text, run->member.run.nCharOfs ); end_run = ME_MakeRun(style, run_flags); @@ -399,6 +485,10 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp, assert(tp->member.para.next_para); assert(tp->member.para.next_para->type == diParagraph); + /* Clear any cached para numbering following this paragraph */ + if (tp->member.para.fmt.wNumbering) + para_num_clear_list( &tp->member.para, &tp->member.para.fmt ); + pNext = tp->member.para.next_para; /* Need to locate end-of-paragraph run here, in order to know end_len */ diff --git a/dlls/riched20/string.c b/dlls/riched20/string.c index 47aceca..cfb149a 100644 --- a/dlls/riched20/string.c +++ b/dlls/riched20/string.c @@ -55,7 +55,7 @@ static void heap_string_free(ME_String *s) } /* Create a buffer (uninitialized string) of size nMaxChars */ -static ME_String *ME_MakeStringB(int nMaxChars) +ME_String *ME_MakeStringEmpty(int nMaxChars) { ME_String *s = make_string( heap_string_free ); @@ -74,7 +74,7 @@ static ME_String *ME_MakeStringB(int nMaxChars) ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars) { - ME_String *s = ME_MakeStringB(nMaxChars); + ME_String *s = ME_MakeStringEmpty(nMaxChars); if (!s) return NULL; memcpy(s->szData, szText, s->nLen * sizeof(WCHAR)); @@ -85,7 +85,7 @@ ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars) ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars) { int i; - ME_String *s = ME_MakeStringB(nMaxChars); + ME_String *s = ME_MakeStringEmpty(nMaxChars); if (!s) return NULL; for (i = 0; i < nMaxChars; i++) -- 2.8.2 From huw at codeweavers.com Mon Oct 10 07:13:05 2016 From: huw at codeweavers.com (Huw Davies) Date: Mon, 10 Oct 2016 13:13:05 +0100 Subject: [PATCH 4/4] wordpad: Add list labelling menu. Message-ID: <1476101585-53773-4-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- programs/wordpad/wordpad.c | 38 +++++++++++++++++++++++++++++++------- programs/wordpad/wordpad.h | 12 +++++++++--- programs/wordpad/wordpad.rc | 10 +++++++++- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/programs/wordpad/wordpad.c b/programs/wordpad/wordpad.c index ea6e11d..dc3918e 100644 --- a/programs/wordpad/wordpad.c +++ b/programs/wordpad/wordpad.c @@ -79,6 +79,8 @@ static WCHAR units_inW[MAX_STRING_LEN]; static WCHAR units_inchW[MAX_STRING_LEN]; static WCHAR units_ptW[MAX_STRING_LEN]; +static int last_bullet = PFN_BULLET; + static LRESULT OnSize( HWND hWnd, WPARAM wParam, LPARAM lParam ); typedef enum @@ -1886,7 +1888,7 @@ static LRESULT OnCreate( HWND hWnd ) AddButton(hFormatBarWnd, 5, ID_ALIGN_CENTER); AddButton(hFormatBarWnd, 6, ID_ALIGN_RIGHT); AddSeparator(hFormatBarWnd); - AddButton(hFormatBarWnd, 7, ID_BULLET); + AddButton(hFormatBarWnd, 7, ID_BULLETONOFF); SendMessageW(hFormatBarWnd, TB_AUTOSIZE, 0, 0); @@ -1994,7 +1996,7 @@ static LRESULT OnUser( HWND hWnd ) SendMessageW(hwndFormatBar, TB_CHECKBUTTON, ID_ALIGN_CENTER, (pf.wAlignment == PFA_CENTER)); SendMessageW(hwndFormatBar, TB_CHECKBUTTON, ID_ALIGN_RIGHT, (pf.wAlignment == PFA_RIGHT)); - SendMessageW(hwndFormatBar, TB_CHECKBUTTON, ID_BULLET, (pf.wNumbering & PFN_BULLET)); + SendMessageW(hwndFormatBar, TB_CHECKBUTTON, ID_BULLETONOFF, pf.wNumbering ? TRUE : FALSE); return 0; } @@ -2351,30 +2353,45 @@ static LRESULT OnCommand( HWND hWnd, WPARAM wParam, LPARAM lParam) SendMessageW(hwndEditor, EM_REDO, 0, 0); return 0; + case ID_BULLETONOFF: case ID_BULLET: + case ID_NUMBERING: + case ID_LCLETTER: + case ID_UCLETTER: + case ID_LCROMAN: + case ID_UCROMAN: { PARAFORMAT2 pf; - + WORD new_number = LOWORD(wParam) - ID_BULLET + PFN_BULLET; pf.cbSize = sizeof(pf); pf.dwMask = PFM_NUMBERING; SendMessageW(hwndEditor, EM_GETPARAFORMAT, 0, (LPARAM)&pf); - pf.dwMask = PFM_NUMBERING | PFM_NUMBERINGSTART | PFM_NUMBERINGTAB | PFM_OFFSET | PFM_OFFSETINDENT; + pf.dwMask = PFM_NUMBERING | PFM_NUMBERINGSTART | PFM_NUMBERINGSTYLE | PFM_NUMBERINGTAB | PFM_OFFSET | PFM_OFFSETINDENT; - if(pf.wNumbering == PFN_BULLET) + if(pf.wNumbering && ((pf.wNumbering == new_number) || (LOWORD(wParam) == ID_BULLETONOFF))) { pf.wNumbering = 0; pf.wNumberingStart = 0; + pf.wNumberingStyle = 0; pf.wNumberingTab = 0; pf.dxOffset = 0; pf.dxStartIndent = -360; } else { - pf.wNumbering = PFN_BULLET; + pf.dxStartIndent = pf.wNumbering ? 0 : 360; + + if (LOWORD(wParam) == ID_BULLETONOFF) + pf.wNumbering = last_bullet; + else + { + pf.wNumbering = new_number; + last_bullet = pf.wNumbering; + } pf.wNumberingStart = 1; + pf.wNumberingStyle = PFNS_PERIOD; pf.wNumberingTab = 360; pf.dxOffset = 360; - pf.dxStartIndent = 360; } SendMessageW(hwndEditor, EM_SETPARAFORMAT, 0, (LPARAM)&pf); @@ -2502,7 +2519,14 @@ static LRESULT OnInitPopupMenu( HWND hWnd, WPARAM wParam ) CheckMenuItem(hMenu, ID_ALIGN_LEFT, (nAlignment == PFA_LEFT) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMenu, ID_ALIGN_CENTER, (nAlignment == PFA_CENTER) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMenu, ID_ALIGN_RIGHT, (nAlignment == PFA_RIGHT) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_BULLET, ((pf.wNumbering == PFN_BULLET) ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(hMenu, ID_NUMBERING, ((pf.wNumbering == PFN_ARABIC) ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(hMenu, ID_LCLETTER, ((pf.wNumbering == PFN_LCLETTER) ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(hMenu, ID_UCLETTER, ((pf.wNumbering == PFN_UCLETTER) ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(hMenu, ID_LCROMAN, ((pf.wNumbering == PFN_LCROMAN) ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(hMenu, ID_UCROMAN, ((pf.wNumbering == PFN_UCROMAN) ? MF_CHECKED : MF_UNCHECKED)); + EnableMenuItem(hMenu, ID_EDIT_UNDO, SendMessageW(hwndEditor, EM_CANUNDO, 0, 0) ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, ID_EDIT_REDO, SendMessageW(hwndEditor, EM_CANREDO, 0, 0) ? diff --git a/programs/wordpad/wordpad.h b/programs/wordpad/wordpad.h index 0cde557..901b19c 100644 --- a/programs/wordpad/wordpad.h +++ b/programs/wordpad/wordpad.h @@ -73,9 +73,15 @@ #define ID_EDIT_CUT 1311 #define ID_EDIT_PASTE 1312 #define ID_EDIT_CLEAR 1313 -#define ID_BULLET 1314 - -#define ID_FONTSETTINGS 1315 +#define ID_BULLETONOFF 1314 +#define ID_BULLET 1315 +#define ID_NUMBERING 1316 +#define ID_LCLETTER 1317 +#define ID_UCLETTER 1318 +#define ID_LCROMAN 1319 +#define ID_UCROMAN 1320 + +#define ID_FONTSETTINGS 1330 #define ID_FORMAT_BOLD 1400 #define ID_FORMAT_ITALIC 1401 diff --git a/programs/wordpad/wordpad.rc b/programs/wordpad/wordpad.rc index ff4f823..147beea 100644 --- a/programs/wordpad/wordpad.rc +++ b/programs/wordpad/wordpad.rc @@ -81,7 +81,15 @@ BEGIN POPUP "F&ormat" BEGIN MENUITEM "&Font...", ID_FONTSETTINGS - MENUITEM "&Bullet points" ID_BULLET + POPUP "&Lists" + BEGIN + MENUITEM "&Bullet points" ID_BULLET + MENUITEM "Numbers" ID_NUMBERING + MENUITEM "Letters - lower case" ID_LCLETTER + MENUITEM "Letters - upper case" ID_UCLETTER + MENUITEM "Roman numerals - lower case" ID_LCROMAN + MENUITEM "Roman numerals - upper case" ID_UCROMAN + END MENUITEM "&Paragraph..." ID_PARAFORMAT MENUITEM "&Tabs..." ID_TABSTOPS POPUP "Backgroun&d" -- 2.8.2 From huw at codeweavers.com Mon Oct 10 07:13:04 2016 From: huw at codeweavers.com (Huw Davies) Date: Mon, 10 Oct 2016 13:13:04 +0100 Subject: [PATCH 3/4] riched20: Add support for roman numeral labelled lists. Message-ID: <1476101585-53773-3-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/para.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index b762df7..d94e213 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -151,11 +151,24 @@ static int para_num_get_num( ME_Paragraph *para ) static ME_String *para_num_get_str( ME_Paragraph *para, WORD num ) { - /* max 5 digits + '(' + ')' */ - ME_String *str = ME_MakeStringEmpty( 5 + 2 ); + /* max 4 Roman letters (representing '8') / decade + '(' + ')' */ + ME_String *str = ME_MakeStringEmpty( 20 + 2 ); WCHAR *p = str->szData; static const WCHAR fmtW[] = {'%', 'd', 0}; static const WORD letter_base[] = { 1, 26, 26 * 26, 26 * 26 * 26 }; + /* roman_base should start on a '5' not a '1', otherwise the 'total' code will need adjusting. + 'N' and 'O' are what MS uses for 5000 and 10000, their version doesn't work well above 30000, + but we'll use 'P' as the obvious extension, this gets us up to 2^16, which is all we care about. */ + static const struct + { + int base; + char letter; + } + roman_base[] = + { + {50000, 'P'}, {10000, 'O'}, {5000, 'N'}, {1000, 'M'}, + {500, 'D'}, {100, 'C'}, {50, 'L'}, {10, 'X'}, {5, 'V'}, {1, 'I'} + }; int i, len; WORD letter, total, char_offset = 0; @@ -194,6 +207,40 @@ static ME_String *para_num_get_str( ME_Paragraph *para, WORD num ) p += len; *p = 0; break; + + case PFN_LCROMAN: + char_offset = 'a' - 'A'; + /* fall through */ + case PFN_UCROMAN: + if (!num) num = 1; + + for (i = 0; i < sizeof(roman_base) / sizeof(roman_base[0]); i++) + { + if (i > 0) + { + if (i % 2 == 0) /* eg 5000, check for 9000 */ + total = roman_base[i].base + 4 * roman_base[i + 1].base; + else /* eg 1000, check for 4000 */ + total = 4 * roman_base[i].base; + + if (num / total) + { + *p++ = roman_base[(i & ~1) + 1].letter + char_offset; + *p++ = roman_base[i - 1].letter + char_offset; + num -= total; + continue; + } + } + + len = num / roman_base[i].base; + while (len--) + { + *p++ = roman_base[i].letter + char_offset; + num -= roman_base[i].base; + } + } + *p = 0; + break; } switch (para->fmt.wNumberingStyle & 0xf00) -- 2.8.2 From sagawa.aki at gmail.com Mon Oct 10 08:53:14 2016 From: sagawa.aki at gmail.com (Akihiro Sagawa) Date: Mon, 10 Oct 2016 22:53:14 +0900 Subject: [2/3] webservices: Add support for decoding decimal numeric character references. Message-ID: <20161010224958.80F8.375B48EC@gmail.com> Signed-off-by: Akihiro Sagawa --- dlls/webservices/reader.c | 50 +++++++++++++++++++++++++++++------------ dlls/webservices/tests/reader.c | 7 ++++++ 2 files changed, 43 insertions(+), 14 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-webservices-Add-support-for-decoding-decimal-numeric.patch Type: text/x-patch Size: 3988 bytes Desc: not available URL: From sagawa.aki at gmail.com Mon Oct 10 08:53:15 2016 From: sagawa.aki at gmail.com (Akihiro Sagawa) Date: Mon, 10 Oct 2016 22:53:15 +0900 Subject: [3/3] webservices: Add support for decoding supplementary characters' references. Message-ID: <20161010225001.80FC.375B48EC@gmail.com> Signed-off-by: Akihiro Sagawa --- dlls/webservices/reader.c | 3 ++- dlls/webservices/tests/reader.c | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0003-webservices-Add-support-for-decoding-supplementary-c.patch Type: text/x-patch Size: 2341 bytes Desc: not available URL: From sagawa.aki at gmail.com Mon Oct 10 08:53:12 2016 From: sagawa.aki at gmail.com (Akihiro Sagawa) Date: Mon, 10 Oct 2016 22:53:12 +0900 Subject: [1/3] webservices: Avoid decoding a nul character reference. Message-ID: <20161010224950.80F4.375B48EC@gmail.com> Signed-off-by: Akihiro Sagawa --- dlls/webservices/reader.c | 2 ++ dlls/webservices/tests/reader.c | 2 ++ 2 files changed, 4 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-webservices-Avoid-decoding-a-nul-character-reference.patch Type: text/x-patch Size: 1292 bytes Desc: not available URL: From nsivov at codeweavers.com Mon Oct 10 09:12:39 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Mon, 10 Oct 2016 17:12:39 +0300 Subject: [v3 PATCH] d2d1: Support shared bitmaps created from dxgi surface Message-ID: <20161010141239.12128-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- v3: check for mismatching d3d device, avoid using factory interface without holding a reference to it v2: fixed test crash on vista dlls/d2d1/bitmap.c | 97 ++++++++++++++++++++++++++++++++++++++++++++--- dlls/d2d1/d2d1_private.h | 2 +- dlls/d2d1/render_target.c | 2 +- dlls/d2d1/tests/d2d1.c | 44 +++++++++++++++++++++ 4 files changed, 137 insertions(+), 8 deletions(-) diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c index b2f2ad7..43904bb 100644 --- a/dlls/d2d1/bitmap.c +++ b/dlls/d2d1/bitmap.c @@ -296,22 +296,32 @@ HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE return *bitmap ? S_OK : E_OUTOFMEMORY; } -HRESULT d2d_bitmap_create_shared(ID2D1Factory *factory, ID3D10Device *target_device, +HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device *target_device, REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) { + D2D1_BITMAP_PROPERTIES d; + ID2D1Factory *factory; + if (IsEqualGUID(iid, &IID_ID2D1Bitmap)) { struct d2d_bitmap *src_impl = unsafe_impl_from_ID2D1Bitmap(data); - D2D1_BITMAP_PROPERTIES d; ID3D10Device *device; + HRESULT hr = S_OK; + ID2D1RenderTarget_GetFactory(render_target, &factory); if (src_impl->factory != factory) - return D2DERR_WRONG_FACTORY; + { + hr = D2DERR_WRONG_FACTORY; + goto failed; + } ID3D10ShaderResourceView_GetDevice(src_impl->view, &device); ID3D10Device_Release(device); if (device != target_device) - return D2DERR_UNSUPPORTED_OPERATION; + { + hr = D2DERR_UNSUPPORTED_OPERATION; + goto failed; + } if (!desc) { @@ -325,15 +335,90 @@ HRESULT d2d_bitmap_create_shared(ID2D1Factory *factory, ID3D10Device *target_dev { WARN("Tried to create bitmap with unsupported format {%#x / %#x}.\n", desc->pixelFormat.format, desc->pixelFormat.alphaMode); - return D2DERR_UNSUPPORTED_PIXEL_FORMAT; + hr = D2DERR_UNSUPPORTED_PIXEL_FORMAT; + goto failed; } if (!(*bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**bitmap)))) - return E_OUTOFMEMORY; + { + hr = E_OUTOFMEMORY; + goto failed; + } d2d_bitmap_init(*bitmap, factory, src_impl->view, src_impl->pixel_size, desc); TRACE("Created bitmap %p.\n", *bitmap); + failed: + ID2D1Factory_Release(factory); + return hr; + } + + if (IsEqualGUID(iid, &IID_IDXGISurface) || IsEqualGUID(iid, &IID_IDXGISurface1)) + { + ID3D10ShaderResourceView *view; + DXGI_SURFACE_DESC surface_desc; + IDXGISurface *surface = data; + ID3D10Resource *resource; + D2D1_SIZE_U pixel_size; + ID3D10Device *device; + HRESULT hr; + + if (FAILED(IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource))) + { + WARN("Failed to get d3d resource from dxgi surface.\n"); + return E_FAIL; + } + + ID3D10Resource_GetDevice(resource, &device); + ID3D10Device_Release(device); + if (device != target_device) + { + ID3D10Resource_Release(resource); + return D2DERR_UNSUPPORTED_OPERATION; + } + + hr = ID3D10Device_CreateShaderResourceView(target_device, resource, NULL, &view); + ID3D10Resource_Release(resource); + if (FAILED(hr)) + { + WARN("Failed to create shader resource view, hr %#x.\n", hr); + return hr; + } + + if (!(*bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**bitmap)))) + { + ID3D10ShaderResourceView_Release(view); + return E_OUTOFMEMORY; + } + + d = *desc; + if (d.dpiX == 0.0f || d.dpiY == 0.0f) + { + float dpi_x, dpi_y; + + ID2D1RenderTarget_GetDpi(render_target, &dpi_x, &dpi_y); + if (d.dpiX == 0.0f) + d.dpiX = dpi_x; + if (d.dpiY == 0.0f) + d.dpiY = dpi_y; + } + + if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc))) + { + WARN("Failed to get surface desc, hr %#x.\n", hr); + ID3D10ShaderResourceView_Release(view); + return hr; + } + + pixel_size.width = surface_desc.Width; + pixel_size.height = surface_desc.Height; + + ID2D1RenderTarget_GetFactory(render_target, &factory); + d2d_bitmap_init(*bitmap, factory, view, pixel_size, &d); + ID3D10ShaderResourceView_Release(view); + ID2D1Factory_Release(factory); + TRACE("Created bitmap %p.\n", *bitmap); + return S_OK; } diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 6cee5ef..c5c3a03 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -236,7 +236,7 @@ struct d2d_bitmap HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; -HRESULT d2d_bitmap_create_shared(ID2D1Factory *factory, ID3D10Device *device, REFIID iid, void *data, +HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device *device, REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; HRESULT d2d_bitmap_create_from_wic_bitmap(ID2D1Factory *factory, ID3D10Device *device, IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index e9a971e..78000af 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -341,7 +341,7 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSharedBitmap(ID2D1R TRACE("iface %p, iid %s, data %p, desc %p, bitmap %p.\n", iface, debugstr_guid(iid), data, desc, bitmap); - if (SUCCEEDED(hr = d2d_bitmap_create_shared(render_target->factory, render_target->device, iid, data, desc, &object))) + if (SUCCEEDED(hr = d2d_bitmap_create_shared(iface, render_target->device, iid, data, desc, &object))) *bitmap = &object->ID2D1Bitmap_iface; return hr; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index ba4be0c..38012ca 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -2046,8 +2046,10 @@ static void test_shared_bitmap(void) ID3D10Device1 *device1, *device2; IWICImagingFactory *wic_factory; ID2D1Bitmap *bitmap1, *bitmap2; + DXGI_SURFACE_DESC surface_desc; ID2D1RenderTarget *rt1, *rt2; D2D1_SIZE_U size = {4, 4}; + IDXGISurface1 *surface3; HWND window1, window2; HRESULT hr; @@ -2171,6 +2173,48 @@ static void test_shared_bitmap(void) ID2D1Bitmap_Release(bitmap2); ID2D1RenderTarget_Release(rt2); + /* Shared DXGI surface. */ + desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + desc.dpiX = 0.0f; + desc.dpiY = 0.0f; + desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, surface2, &desc, &rt2); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + bitmap_desc.dpiX = 0.0f; + bitmap_desc.dpiY = 0.0f; + + hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface, surface2, &bitmap_desc, &bitmap2); + ok(SUCCEEDED(hr) || broken(hr == E_INVALIDARG) /* vista */, "Failed to create bitmap, hr %#x.\n", hr); + + if (SUCCEEDED(hr)) + { + size = ID2D1Bitmap_GetPixelSize(bitmap2); + hr = IDXGISurface_GetDesc(surface2, &surface_desc); + ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr); + ok(size.width == surface_desc.Width && size.height == surface_desc.Height, "Got wrong bitmap size.\n"); + + ID2D1Bitmap_Release(bitmap2); + + /* IDXGISurface1 is supported too. */ + if (IDXGISurface_QueryInterface(surface2, &IID_IDXGISurface1, (void **)&surface3) == S_OK) + { + hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface1, surface3, &bitmap_desc, &bitmap2); + ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr); + + ID2D1Bitmap_Release(bitmap2); + IDXGISurface1_Release(surface3); + } + } + + ID2D1RenderTarget_Release(rt2); + ID2D1Bitmap_Release(bitmap1); ID2D1RenderTarget_Release(rt1); ID2D1Factory_Release(factory2); -- 2.9.3 From nsivov at codeweavers.com Mon Oct 10 09:29:56 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Mon, 10 Oct 2016 17:29:56 +0300 Subject: [PATCH] d2d1: Make some of drawing calls a wrappers over DrawGeometry() Message-ID: <20161010142956.12746-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/d2d1/render_target.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index 78000af..4417b85 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -466,8 +466,21 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawLine(ID2D1RenderTarget * static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawRectangle(ID2D1RenderTarget *iface, const D2D1_RECT_F *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) { - FIXME("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n", + struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface); + ID2D1RectangleGeometry *geometry; + HRESULT hr; + + TRACE("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p.\n", iface, rect, brush, stroke_width, stroke_style); + + if (FAILED(hr = ID2D1Factory_CreateRectangleGeometry(render_target->factory, rect, &geometry))) + { + ERR("Failed to create geometry, hr %#x.\n", hr); + return; + } + + ID2D1RenderTarget_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style); + ID2D1RectangleGeometry_Release(geometry); } static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRectangle(ID2D1RenderTarget *iface, @@ -492,8 +505,21 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRectangle(ID2D1RenderTar static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawRoundedRectangle(ID2D1RenderTarget *iface, const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) { - FIXME("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n", + struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface); + ID2D1RoundedRectangleGeometry *geometry; + HRESULT hr; + + TRACE("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p.\n", iface, rect, brush, stroke_width, stroke_style); + + if (FAILED(hr = ID2D1Factory_CreateRoundedRectangleGeometry(render_target->factory, rect, &geometry))) + { + ERR("Failed to create geometry, hr %#x.\n", hr); + return; + } + + ID2D1RenderTarget_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style); + ID2D1RoundedRectangleGeometry_Release(geometry); } static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRoundedRectangle(ID2D1RenderTarget *iface, @@ -518,8 +544,21 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRoundedRectangle(ID2D1Re static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawEllipse(ID2D1RenderTarget *iface, const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) { - FIXME("iface %p, ellipse %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n", + struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface); + ID2D1EllipseGeometry *geometry; + HRESULT hr; + + TRACE("iface %p, ellipse %p, brush %p, stroke_width %.8e, stroke_style %p.\n", iface, ellipse, brush, stroke_width, stroke_style); + + if (FAILED(hr = ID2D1Factory_CreateEllipseGeometry(render_target->factory, ellipse, &geometry))) + { + ERR("Failed to create geometry, hr %#x.\n", hr); + return; + } + + ID2D1RenderTarget_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style); + ID2D1EllipseGeometry_Release(geometry); } static void STDMETHODCALLTYPE d2d_d3d_render_target_FillEllipse(ID2D1RenderTarget *iface, -- 2.9.3 From hans at codeweavers.com Mon Oct 10 09:31:33 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Mon, 10 Oct 2016 16:31:33 +0200 Subject: [1/3] webservices: Avoid decoding a nul character reference. In-Reply-To: <20161010224950.80F4.375B48EC@gmail.com> References: <20161010224950.80F4.375B48EC@gmail.com> Message-ID: <1476109893.6573.243.camel@codeweavers.com> Signed-off-by: Hans Leidekker From hans at codeweavers.com Mon Oct 10 09:31:57 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Mon, 10 Oct 2016 16:31:57 +0200 Subject: [2/3] webservices: Add support for decoding decimal numeric character references. In-Reply-To: <20161010224958.80F8.375B48EC@gmail.com> References: <20161010224958.80F8.375B48EC@gmail.com> Message-ID: <1476109917.6573.244.camel@codeweavers.com> Signed-off-by: Hans Leidekker From hans at codeweavers.com Mon Oct 10 09:32:12 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Mon, 10 Oct 2016 16:32:12 +0200 Subject: [3/3] webservices: Add support for decoding supplementary characters' references. In-Reply-To: <20161010225001.80FC.375B48EC@gmail.com> References: <20161010225001.80FC.375B48EC@gmail.com> Message-ID: <1476109932.6573.245.camel@codeweavers.com> Signed-off-by: Hans Leidekker From rpisl at seznam.cz Mon Oct 10 09:35:38 2016 From: rpisl at seznam.cz (Roman Pisl) Date: Mon, 10 Oct 2016 16:35:38 +0200 Subject: [PATCH 1/5] shell32/systray: implement NIM_SETVERSION Message-ID: <1476110142-1088-1-git-send-email-rpisl@seznam.cz> Signed-off-by: Roman Pisl --- dlls/shell32/systray.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dlls/shell32/systray.c b/dlls/shell32/systray.c index dfa30ff..a043912 100644 --- a/dlls/shell32/systray.c +++ b/dlls/shell32/systray.c @@ -234,6 +234,8 @@ noicon: } if (data->uFlags & NIF_GUID) data->guidItem = nid->guidItem; + if (dwMessage == NIM_SETVERSION) + data->u.uVersion = nid->u.uVersion; /* FIXME: balloon icon */ cds.lpData = data; -- 2.7.3 From rpisl at seznam.cz Mon Oct 10 09:35:40 2016 From: rpisl at seznam.cz (Roman Pisl) Date: Mon, 10 Oct 2016 16:35:40 +0200 Subject: [PATCH 3/5] explorer/systray: implement NIM_SETVERSION In-Reply-To: <1476110142-1088-1-git-send-email-rpisl@seznam.cz> References: <1476110142-1088-1-git-send-email-rpisl@seznam.cz> Message-ID: <1476110142-1088-3-git-send-email-rpisl@seznam.cz> Signed-off-by: Roman Pisl --- programs/explorer/systray.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/programs/explorer/systray.c b/programs/explorer/systray.c index 97cffbc..bd05a4f 100644 --- a/programs/explorer/systray.c +++ b/programs/explorer/systray.c @@ -77,6 +77,7 @@ struct icon UINT info_flags; /* flags for info balloon */ UINT info_timeout; /* timeout for info balloon */ HICON info_icon; /* info balloon icon */ + UINT version; /* notify icon api version */ }; static struct list icon_list = LIST_INIT( icon_list ); @@ -586,6 +587,12 @@ static BOOL handle_incoming(HWND hwndSource, COPYDATASTRUCT *cds) case NIM_MODIFY: if (icon) ret = modify_icon( icon, &nid ); break; + case NIM_SETVERSION: + if (nid.u.uVersion <= NOTIFY_VERSION_4) { + icon->version = nid.u.uVersion; + ret = TRUE; + } + break; default: WINE_FIXME("unhandled tray message: %ld\n", cds->dwData); break; @@ -790,6 +797,9 @@ static LRESULT WINAPI tray_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l case WM_RBUTTONDBLCLK: case WM_MBUTTONDBLCLK: { + WPARAM wpar; + BOOL oldver; + BOOL ret; MSG message; struct icon *icon = icon_from_point( (short)LOWORD(lparam), (short)HIWORD(lparam) ); if (!icon) break; @@ -803,8 +813,26 @@ static LRESULT WINAPI tray_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l message.lParam = lparam; SendMessageW( icon->tooltip, TTM_RELAYEVENT, 0, (LPARAM)&message ); - if (!PostMessageW( icon->owner, icon->callback_message, (WPARAM) icon->id, (LPARAM) msg ) && - GetLastError() == ERROR_INVALID_WINDOW_HANDLE) + oldver = icon->version <= NOTIFY_VERSION; + if (oldver) { + /* 0 up to NOTIFYICON_VERSION (=3) */ + wpar = icon->id; + } else { + /* NOTIFYICON_VERSION_4 */ + RECT rect; + WORD x, y; + + rect = get_icon_rect( icon ); + MapWindowPoints( tray_window, 0, (POINT *)&rect, 2 ); + x = rect.left + LOWORD(lparam); + y = rect.top + HIWORD(lparam); + wpar = MAKEWPARAM(x, y); + } + + ret = PostMessageW(icon->owner, icon->callback_message, wpar, + oldver ? msg : MAKELPARAM(msg, icon->id)); + + if (!ret && (GetLastError() == ERROR_INVALID_WINDOW_HANDLE)) { WINE_WARN("application window was destroyed without removing " "notification icon, removing automatically\n"); -- 2.7.3 From rpisl at seznam.cz Mon Oct 10 09:35:41 2016 From: rpisl at seznam.cz (Roman Pisl) Date: Mon, 10 Oct 2016 16:35:41 +0200 Subject: [PATCH 4/5] winex11.drv/systray: send WM_CONTEXTMENU on WM_RBUTTONUP and NIN_SELECT on WM_LBUTTONUP In-Reply-To: <1476110142-1088-1-git-send-email-rpisl@seznam.cz> References: <1476110142-1088-1-git-send-email-rpisl@seznam.cz> Message-ID: <1476110142-1088-4-git-send-email-rpisl@seznam.cz> Signed-off-by: Roman Pisl --- dlls/winex11.drv/systray.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/dlls/winex11.drv/systray.c b/dlls/winex11.drv/systray.c index 896ffab..78cba87 100644 --- a/dlls/winex11.drv/systray.c +++ b/dlls/winex11.drv/systray.c @@ -509,6 +509,25 @@ static LRESULT WINAPI tray_icon_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPAR ret = PostMessageW(icon->owner, icon->callback_message, wpar, oldver ? msg : MAKELPARAM(msg, icon->id)); + if (ret && icon->version > 0) { + switch (msg) { + case WM_RBUTTONUP: + /* notify the owner hwnd of the message */ + TRACE("relaying 0x%x\n", WM_CONTEXTMENU); + ret = PostMessageW(icon->owner, icon->callback_message, wpar, + oldver ? WM_CONTEXTMENU : MAKELPARAM(WM_CONTEXTMENU, icon->id)); + break; + case WM_LBUTTONUP: + /* notify the owner hwnd of the message */ + TRACE("relaying 0x%x\n", NIN_SELECT); + ret = PostMessageW(icon->owner, icon->callback_message, wpar, + oldver ? NIN_SELECT : MAKELPARAM(NIN_SELECT, icon->id)); + break; + default: + break; + } + } + if (!ret && (GetLastError() == ERROR_INVALID_WINDOW_HANDLE)) { WARN( "application window was destroyed, removing icon %u\n", icon->id ); -- 2.7.3 From rpisl at seznam.cz Mon Oct 10 09:35:39 2016 From: rpisl at seznam.cz (Roman Pisl) Date: Mon, 10 Oct 2016 16:35:39 +0200 Subject: [PATCH 2/5] winex11.drv/systray: implement NIM_SETVERSION In-Reply-To: <1476110142-1088-1-git-send-email-rpisl@seznam.cz> References: <1476110142-1088-1-git-send-email-rpisl@seznam.cz> Message-ID: <1476110142-1088-2-git-send-email-rpisl@seznam.cz> Signed-off-by: Roman Pisl --- dlls/winex11.drv/systray.c | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/dlls/winex11.drv/systray.c b/dlls/winex11.drv/systray.c index c7e7013..896ffab 100644 --- a/dlls/winex11.drv/systray.c +++ b/dlls/winex11.drv/systray.c @@ -65,6 +65,7 @@ struct tray_icon UINT info_flags; /* flags for info balloon */ UINT info_timeout; /* timeout for info balloon */ HICON info_icon; /* info balloon icon */ + UINT version; /* notify icon api version */ }; static struct list icon_list = LIST_INIT( icon_list ); @@ -484,15 +485,37 @@ static LRESULT WINAPI tray_icon_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPAR case WM_LBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_MBUTTONDBLCLK: - /* notify the owner hwnd of the message */ - TRACE("relaying 0x%x\n", msg); - ret = PostMessageW(icon->owner, icon->callback_message, icon->id, msg); - if (!ret && (GetLastError() == ERROR_INVALID_WINDOW_HANDLE)) { - WARN( "application window was destroyed, removing icon %u\n", icon->id ); - delete_icon( icon ); + WPARAM wpar; + BOOL oldver; + + oldver = icon->version <= NOTIFY_VERSION; + if (oldver) { + /* 0 up to NOTIFYICON_VERSION (=3) */ + wpar = icon->id; + } else { + /* NOTIFYICON_VERSION_4 */ + RECT rect; + WORD x, y; + + GetWindowRect( icon->window, &rect ); + x = rect.left + LOWORD(lparam); + y = rect.top + HIWORD(lparam); + wpar = MAKEWPARAM(x, y); + } + + /* notify the owner hwnd of the message */ + TRACE("relaying 0x%x\n", msg); + ret = PostMessageW(icon->owner, icon->callback_message, wpar, + oldver ? msg : MAKELPARAM(msg, icon->id)); + + if (!ret && (GetLastError() == ERROR_INVALID_WINDOW_HANDLE)) + { + WARN( "application window was destroyed, removing icon %u\n", icon->id ); + delete_icon( icon ); + } + return 0; } - return 0; case WM_WINDOWPOSCHANGED: update_systray_balloon_position(); @@ -834,6 +857,14 @@ int CDECL wine_notify_icon( DWORD msg, NOTIFYICONDATAW *data ) case NIM_MODIFY: if ((icon = get_icon( data->hWnd, data->uID ))) ret = modify_icon( icon, data ); break; + case NIM_SETVERSION: + if (data->u.uVersion <= NOTIFY_VERSION_4) { + if ((icon = get_icon( data->hWnd, data->uID ))) { + icon->version = data->u.uVersion; + ret = TRUE; + } + } + break; case 0xdead: /* Wine extension: owner window has died */ cleanup_icons( data->hWnd ); break; -- 2.7.3 From rpisl at seznam.cz Mon Oct 10 09:35:42 2016 From: rpisl at seznam.cz (Roman Pisl) Date: Mon, 10 Oct 2016 16:35:42 +0200 Subject: [PATCH 5/5] explorer/systray: send WM_CONTEXTMENU on WM_RBUTTONUP and NIN_SELECT on WM_LBUTTONUP In-Reply-To: <1476110142-1088-1-git-send-email-rpisl@seznam.cz> References: <1476110142-1088-1-git-send-email-rpisl@seznam.cz> Message-ID: <1476110142-1088-5-git-send-email-rpisl@seznam.cz> Fixes https://bugs.winehq.org/show_bug.cgi?id=29412 Tested on Gentoo Linux and Qt 4.8/5.5. Signed-off-by: Roman Pisl --- programs/explorer/systray.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/programs/explorer/systray.c b/programs/explorer/systray.c index bd05a4f..fe86403 100644 --- a/programs/explorer/systray.c +++ b/programs/explorer/systray.c @@ -832,6 +832,25 @@ static LRESULT WINAPI tray_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l ret = PostMessageW(icon->owner, icon->callback_message, wpar, oldver ? msg : MAKELPARAM(msg, icon->id)); + if (ret && icon->version > 0) { + switch (msg) { + case WM_RBUTTONUP: + /* notify the owner hwnd of the message */ + WINE_TRACE("relaying 0x%x\n", WM_CONTEXTMENU); + ret = PostMessageW(icon->owner, icon->callback_message, wpar, + oldver ? WM_CONTEXTMENU : MAKELPARAM(WM_CONTEXTMENU, icon->id)); + break; + case WM_LBUTTONUP: + /* notify the owner hwnd of the message */ + WINE_TRACE("relaying 0x%x\n", NIN_SELECT); + ret = PostMessageW(icon->owner, icon->callback_message, wpar, + oldver ? NIN_SELECT : MAKELPARAM(NIN_SELECT, icon->id)); + break; + default: + break; + } + } + if (!ret && (GetLastError() == ERROR_INVALID_WINDOW_HANDLE)) { WINE_WARN("application window was destroyed without removing " -- 2.7.3 From sebastian at fds-team.de Mon Oct 10 10:15:39 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Mon, 10 Oct 2016 17:15:39 +0200 Subject: ntoskrnl.exe: Use completion routine to transfer result of IRP back to server. Message-ID: <8b21b481-3401-4852-3028-57f80ecf2c80@fds-team.de> Signed-off-by: Sebastian Lackner --- No longer abuses UserIosb to store the IRP handle. Other parts of Wine pass an IO_STATUS_BLOCK pointer, and there would be no good way to distinguish both. When using a completion, we can store the handle in the Context parameter. dlls/ntoskrnl.exe/ntoskrnl.c | 83 ++++++++++++++++++++----------------------- include/ddk/wdm.h | 12 ++++++ 2 files changed, 51 insertions(+), 44 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index cf87f7a..909bf6f 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -172,16 +172,40 @@ static HANDLE get_device_manager(void) return ret; } -static void dispatch_irp( DEVICE_OBJECT *device, IRP *irp ) +/* transfer result of IRP back to wineserver */ +static NTSTATUS WINAPI dispatch_irp_completion( DEVICE_OBJECT *device, IRP *irp, void *context ) +{ + FILE_OBJECT *file = irp->Tail.Overlay.OriginalFileObject; + void *out_buff = irp->UserBuffer; + HANDLE handle = context; + + SERVER_START_REQ( set_irp_result ) + { + req->handle = wine_server_obj_handle( handle ); + req->status = irp->IoStatus.u.Status; + req->file_ptr = wine_server_client_ptr( file ); + if (irp->IoStatus.u.Status >= 0) + { + req->size = irp->IoStatus.Information; + if (out_buff) wine_server_add_data( req, out_buff, irp->IoStatus.Information ); + } + wine_server_call( req ); + } + SERVER_END_REQ; + + HeapFree( GetProcessHeap(), 0, out_buff ); + return STATUS_SUCCESS; +} + +static void dispatch_irp( DEVICE_OBJECT *device, IRP *irp, HANDLE irp_handle ) { LARGE_INTEGER count; + IoSetCompletionRoutine( irp, dispatch_irp_completion, irp_handle, TRUE, TRUE, TRUE ); KeQueryTickCount( &count ); /* update the global KeTickCount */ device->CurrentIrp = irp; - IoCallDriver( device, irp ); - device->CurrentIrp = NULL; } @@ -211,7 +235,6 @@ static NTSTATUS dispatch_create( const irp_params_t *params, void *in_buff, ULON irpsp = IoGetNextIrpStackLocation( irp ); irpsp->MajorFunction = IRP_MJ_CREATE; irpsp->DeviceObject = device; - irpsp->CompletionRoutine = NULL; irpsp->Parameters.Create.SecurityContext = NULL; /* FIXME */ irpsp->Parameters.Create.Options = params->create.options; irpsp->Parameters.Create.ShareAccess = params->create.sharing; @@ -222,10 +245,10 @@ static NTSTATUS dispatch_create( const irp_params_t *params, void *in_buff, ULON irp->RequestorMode = UserMode; irp->AssociatedIrp.SystemBuffer = NULL; irp->UserBuffer = NULL; - irp->UserIosb = irp_handle; /* note: we abuse UserIosb to store the server irp handle */ + irp->UserIosb = NULL; irp->UserEvent = NULL; - dispatch_irp( device, irp ); + dispatch_irp( device, irp, irp_handle ); return STATUS_SUCCESS; } @@ -254,16 +277,15 @@ static NTSTATUS dispatch_close( const irp_params_t *params, void *in_buff, ULONG irpsp = IoGetNextIrpStackLocation( irp ); irpsp->MajorFunction = IRP_MJ_CLOSE; irpsp->DeviceObject = device; - irpsp->CompletionRoutine = NULL; irp->Tail.Overlay.OriginalFileObject = file; irp->RequestorMode = UserMode; irp->AssociatedIrp.SystemBuffer = NULL; irp->UserBuffer = NULL; - irp->UserIosb = irp_handle; /* note: we abuse UserIosb to store the server irp handle */ + irp->UserIosb = NULL; irp->UserEvent = NULL; - dispatch_irp( device, irp ); + dispatch_irp( device, irp, irp_handle ); HeapFree( GetProcessHeap(), 0, file ); /* FIXME: async close processing not supported */ return STATUS_SUCCESS; @@ -290,9 +312,8 @@ static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG offset.QuadPart = params->read.pos; - /* note: we abuse UserIosb to store the server irp handle */ if (!(irp = IoBuildSynchronousFsdRequest( IRP_MJ_READ, device, out_buff, out_size, - &offset, NULL, irp_handle ))) + &offset, NULL, NULL ))) { HeapFree( GetProcessHeap(), 0, out_buff ); return STATUS_NO_MEMORY; @@ -304,7 +325,7 @@ static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG irpsp = IoGetNextIrpStackLocation( irp ); irpsp->Parameters.Read.Key = params->read.key; - dispatch_irp( device, irp ); + dispatch_irp( device, irp, irp_handle ); return STATUS_SUCCESS; } @@ -327,9 +348,8 @@ static NTSTATUS dispatch_write( const irp_params_t *params, void *in_buff, ULONG offset.QuadPart = params->write.pos; - /* note: we abuse UserIosb to store the server irp handle */ if (!(irp = IoBuildSynchronousFsdRequest( IRP_MJ_WRITE, device, in_buff, in_size, - &offset, NULL, irp_handle ))) + &offset, NULL, NULL ))) return STATUS_NO_MEMORY; irp->Tail.Overlay.OriginalFileObject = file; @@ -338,7 +358,7 @@ static NTSTATUS dispatch_write( const irp_params_t *params, void *in_buff, ULONG irpsp = IoGetNextIrpStackLocation( irp ); irpsp->Parameters.Write.Key = params->write.key; - dispatch_irp( device, irp ); + dispatch_irp( device, irp, irp_handle ); return STATUS_SUCCESS; } @@ -357,15 +377,14 @@ static NTSTATUS dispatch_flush( const irp_params_t *params, void *in_buff, ULONG TRACE( "device %p file %p\n", device, file ); - /* note: we abuse UserIosb to store the server irp handle */ if (!(irp = IoBuildSynchronousFsdRequest( IRP_MJ_FLUSH_BUFFERS, device, NULL, 0, - NULL, NULL, irp_handle ))) + NULL, NULL, NULL ))) return STATUS_NO_MEMORY; irp->Tail.Overlay.OriginalFileObject = file; irp->RequestorMode = UserMode; - dispatch_irp( device, irp ); + dispatch_irp( device, irp, irp_handle ); return STATUS_SUCCESS; } @@ -398,9 +417,8 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG } } - /* note: we abuse UserIosb to store the server handle to the ioctl */ irp = IoBuildDeviceIoControlRequest( params->ioctl.code, device, in_buff, in_size, out_buff, out_size, - FALSE, NULL, irp_handle ); + FALSE, NULL, NULL ); if (!irp) { HeapFree( GetProcessHeap(), 0, out_buff ); @@ -410,7 +428,7 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG irp->Tail.Overlay.OriginalFileObject = file; irp->RequestorMode = UserMode; - dispatch_irp( device, irp ); + dispatch_irp( device, irp, irp_handle ); return STATUS_SUCCESS; } @@ -1390,7 +1408,6 @@ VOID WINAPI IoCompleteRequest( IRP *irp, UCHAR priority_boost ) IO_STACK_LOCATION *irpsp; PIO_COMPLETION_ROUTINE routine; NTSTATUS status, stat; - HANDLE handle; int call_flag = 0; TRACE( "%p %u\n", irp, priority_boost ); @@ -1422,28 +1439,6 @@ VOID WINAPI IoCompleteRequest( IRP *irp, UCHAR priority_boost ) } } - handle = (HANDLE)irp->UserIosb; - if (handle) - { - void *out_buff = irp->UserBuffer; - FILE_OBJECT *file = irp->Tail.Overlay.OriginalFileObject; - - SERVER_START_REQ( set_irp_result ) - { - req->handle = wine_server_obj_handle( handle ); - req->status = irp->IoStatus.u.Status; - req->file_ptr = wine_server_client_ptr( file ); - if (irp->IoStatus.u.Status >= 0) - { - req->size = irp->IoStatus.Information; - if (out_buff) wine_server_add_data( req, out_buff, irp->IoStatus.Information ); - } - wine_server_call( req ); - } - SERVER_END_REQ; - HeapFree( GetProcessHeap(), 0, out_buff ); - } - IoFreeIrp( irp ); } diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 918797e..5602f7d 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1189,6 +1189,18 @@ NTSTATUS WINAPI ObCloseHandle(IN HANDLE handle); # endif #endif +static inline void IoSetCompletionRoutine(IRP *irp, PIO_COMPLETION_ROUTINE routine, void *context, + BOOLEAN on_success, BOOLEAN on_error, BOOLEAN on_cancel) +{ + IO_STACK_LOCATION *irpsp = IoGetNextIrpStackLocation(irp); + irpsp->CompletionRoutine = routine; + irpsp->Context = context; + irpsp->Control = 0; + if (on_success) irpsp->Control |= SL_INVOKE_ON_SUCCESS; + if (on_error) irpsp->Control |= SL_INVOKE_ON_ERROR; + if (on_cancel) irpsp->Control |= SL_INVOKE_ON_CANCEL; +} + #define KernelMode 0 #define UserMode 1 -- 2.9.0 From madewokherd at gmail.com Mon Oct 10 11:43:14 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Mon, 10 Oct 2016 11:43:14 -0500 Subject: [PATCH] gdiplus: assign error return (Coverity) In-Reply-To: <20161009072452.18039-1-marcus@jet.franken.de> References: <20161009072452.18039-1-marcus@jet.franken.de> Message-ID: Signed-off-by: Vincent Povirk From austinenglish at gmail.com Mon Oct 10 20:17:46 2016 From: austinenglish at gmail.com (Austin English) Date: Mon, 10 Oct 2016 20:17:46 -0500 Subject: ntoskrnl.exe: add KeAcquireInStackQueuedSpinLock stub Message-ID: For https://bugs.winehq.org/show_bug.cgi?id=41472 -- -Austin GPG: 14FB D7EA A041 937B -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-ntoskrnl.exe-add-KeAcquireInStackQueuedSpinLock-stub.patch Type: text/x-diff Size: 3066 bytes Desc: not available URL: From dmitry at baikal.ru Mon Oct 10 20:30:03 2016 From: dmitry at baikal.ru (Dmitry Timoshkov) Date: Tue, 11 Oct 2016 09:30:03 +0800 Subject: include/d2d1.idl: Remove duplicate typedefs. Message-ID: <20161011093003.c2f286e0.dmitry@baikal.ru> This fixes 32-bit part of a wow64 build. Signed-off-by: Dmitry Timoshkov --- include/d2d1.idl | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/d2d1.idl b/include/d2d1.idl index 0e944e1..6d39e88 100644 --- a/include/d2d1.idl +++ b/include/d2d1.idl @@ -42,12 +42,10 @@ cpp_quote("#ifndef __dwrite_h__") typedef struct DWRITE_GLYPH_RUN DWRITE_GLYPH_RUN; cpp_quote("#endif /* __dwrite_h__ */") -typedef D2D_POINT_2F D2D1_POINT_2F; typedef D2D_MATRIX_3X2_F D2D1_MATRIX_3X2_F; typedef D2D_RECT_F D2D1_RECT_F; typedef D2D_SIZE_F D2D1_SIZE_F; typedef UINT64 D2D1_TAG; -typedef D2D_SIZE_U D2D1_SIZE_U; typedef D2D_POINT_2U D2D1_POINT_2U; typedef D2D_RECT_U D2D1_RECT_U; typedef D2D_COLOR_F D2D1_COLOR_F; -- 2.10.1 From austinenglish at gmail.com Mon Oct 10 20:46:59 2016 From: austinenglish at gmail.com (Austin English) Date: Mon, 10 Oct 2016 20:46:59 -0500 Subject: ntdll: give user an error message if WINEARCH is not win32/win64 Message-ID: Fixes https://bugs.winehq.org/show_bug.cgi?id=41378 See also https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=838474 -- -Austin GPG: 14FB D7EA A041 937B -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-ntdll-give-user-an-error-message-if-WINEARCH-is-not-.patch Type: text/x-diff Size: 958 bytes Desc: not available URL: From ken at codeweavers.com Mon Oct 10 22:38:13 2016 From: ken at codeweavers.com (Ken Thomases) Date: Mon, 10 Oct 2016 22:38:13 -0500 Subject: winemac: Post WINDOW_FRAME_CHANGED with the non-fullscreen frame when exiting of fullscreen mode begins. Message-ID: <1476157093-85031-1-git-send-email-ken@codeweavers.com> We had been posting it when exiting fullscreen mode ended. However, certain events during exiting could provoke the back-end to assert the window frame as it knows it, which would be the one from full-screen mode. This would be handled by the Cocoa thread after exiting full-screen mode. So, the window would animate to its pre-fullscreen frame and then spontaneously go back to covering the screen. This would be Windows-style fullscreen rather than Cocoa-style and there'd be no obvious way to get out. The problem occurs on macOS 10.12 (Sierra) due to a change in what methods it calls on the window while exiting fullscreen. Signed-off-by: Ken Thomases --- dlls/winemac.drv/cocoa_window.m | 48 ++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index 8e8ac9f..e638991 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -1842,6 +1842,30 @@ - (void) postBroughtForwardEvent macdrv_release_event(event); } + - (void) postWindowFrameChanged:(NSRect)frame fullscreen:(BOOL)isFullscreen resizing:(BOOL)resizing + { + macdrv_event* event; + NSUInteger style = self.styleMask; + + if (isFullscreen) + style |= NSFullScreenWindowMask; + else + style &= ~NSFullScreenWindowMask; + frame = [[self class] contentRectForFrameRect:frame styleMask:style]; + [[WineApplicationController sharedController] flipRect:&frame]; + + /* Coalesce events by discarding any previous ones still in the queue. */ + [queue discardEventsMatchingMask:event_mask_for_type(WINDOW_FRAME_CHANGED) + forWindow:self]; + + event = macdrv_create_event(WINDOW_FRAME_CHANGED, self); + event->window_frame_changed.frame = cgrect_win_from_mac(NSRectToCGRect(frame)); + event->window_frame_changed.fullscreen = isFullscreen; + event->window_frame_changed.in_resize = resizing; + [queue postEvent:event]; + macdrv_release_event(event); + } + - (void) updateForCursorClipping { [self adjustFeaturesForState]; @@ -2589,7 +2613,6 @@ - (void)windowDidResignKey:(NSNotification *)notification - (void)windowDidResize:(NSNotification *)notification { - macdrv_event* event; NSRect frame = self.wine_fractionalFrame; if ([self inLiveResize]) @@ -2600,28 +2623,18 @@ - (void)windowDidResize:(NSNotification *)notification resizingFromTop = TRUE; } - frame = [self contentRectForFrameRect:frame]; - if (ignore_windowResize || exitingFullScreen) return; if ([self preventResizing]) { - [self setContentMinSize:frame.size]; - [self setContentMaxSize:frame.size]; + NSRect contentRect = [self contentRectForFrameRect:frame]; + [self setContentMinSize:contentRect.size]; + [self setContentMaxSize:contentRect.size]; } - [[WineApplicationController sharedController] flipRect:&frame]; - - /* Coalesce events by discarding any previous ones still in the queue. */ - [queue discardEventsMatchingMask:event_mask_for_type(WINDOW_FRAME_CHANGED) - forWindow:self]; - - event = macdrv_create_event(WINDOW_FRAME_CHANGED, self); - event->window_frame_changed.frame = cgrect_win_from_mac(NSRectToCGRect(frame)); - event->window_frame_changed.fullscreen = ([self styleMask] & NSFullScreenWindowMask) != 0; - event->window_frame_changed.in_resize = [self inLiveResize]; - [queue postEvent:event]; - macdrv_release_event(event); + [self postWindowFrameChanged:frame + fullscreen:([self styleMask] & NSFullScreenWindowMask) != 0 + resizing:[self inLiveResize]]; [[[self contentView] inputContext] invalidateCharacterCoordinates]; [self updateFullscreen]; @@ -2683,6 +2696,7 @@ - (void) windowWillEnterFullScreen:(NSNotification*)notification - (void) windowWillExitFullScreen:(NSNotification*)notification { exitingFullScreen = TRUE; + [self postWindowFrameChanged:nonFullscreenFrame fullscreen:FALSE resizing:FALSE]; } - (void)windowWillMiniaturize:(NSNotification *)notification -- 2.8.2 From austinenglish at gmail.com Mon Oct 10 22:42:47 2016 From: austinenglish at gmail.com (Austin English) Date: Mon, 10 Oct 2016 22:42:47 -0500 Subject: [PATCH 1/2] shell32: add SHRemoveLocalizedName stub Message-ID: For https://bugs.winehq.org/show_bug.cgi?id=41449 -- -Austin GPG: 14FB D7EA A041 937B -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-shell32-add-SHRemoveLocalizedName-stub.patch Type: text/x-diff Size: 1269 bytes Desc: not available URL: From austinenglish at gmail.com Mon Oct 10 22:44:06 2016 From: austinenglish at gmail.com (Austin English) Date: Mon, 10 Oct 2016 22:44:06 -0500 Subject: [PATCH 2/2] shell32: add SHCreateSessionKey stub (try 2) Message-ID: For https://bugs.winehq.org/show_bug.cgi?id=35630 Thanks to Michael Müller for reviewing/helping improve try 1. -- -Austin GPG: 14FB D7EA A041 937B -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-shell32-add-SHCreateSessionKey-stub-try-2.patch Type: text/x-diff Size: 2750 bytes Desc: not available URL: From austinenglish at gmail.com Tue Oct 11 01:33:01 2016 From: austinenglish at gmail.com (Austin English) Date: Tue, 11 Oct 2016 01:33:01 -0500 Subject: [PATCH 1/2] shell32: add SHRemoveLocalizedName stub (try 2) Message-ID: Try 2: add missing WINAPI -- -Austin GPG: 14FB D7EA A041 937B -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-shell32-add-SHRemoveLocalizedName-stub-try-2.patch Type: text/x-diff Size: 1284 bytes Desc: not available URL: From austinenglish at gmail.com Tue Oct 11 01:33:35 2016 From: austinenglish at gmail.com (Austin English) Date: Tue, 11 Oct 2016 01:33:35 -0500 Subject: [PATCH 2/2] shell32: add SHCreateSessionKey stub (try 2) (resend) Message-ID: -- -Austin GPG: 14FB D7EA A041 937B -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-shell32-add-SHCreateSessionKey-stub-try-2.patch Type: text/x-diff Size: 2750 bytes Desc: not available URL: From alexhenrie24 at gmail.com Tue Oct 11 02:01:10 2016 From: alexhenrie24 at gmail.com (Alex Henrie) Date: Tue, 11 Oct 2016 01:01:10 -0600 Subject: [PATCH resend] winex11: Send SC_KEYMENU on managed windows. Message-ID: <20161011070110.24782-1-alexhenrie24@gmail.com> Fixes https://bugs.winehq.org/show_bug.cgi?id=21918 Wine Staging has included this patch since 1.9.12 with no reported problems. Signed-off-by: Alex Henrie --- dlls/user32/tests/msg.c | 5 ++--- dlls/winex11.drv/window.c | 11 ----------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index b132dfe..f50a273 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -8001,8 +8001,7 @@ static void test_accelerators(void) keybd_event(VK_MENU, 0, 0, 0); keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0); pump_msg_loop(hwnd, 0); - /* this test doesn't pass in Wine for managed windows */ - ok_sequence(WmAltPressRelease, "Alt press/release", TRUE); + ok_sequence(WmAltPressRelease, "Alt press/release", FALSE); trace("testing VK_F1 press/release\n"); keybd_event(VK_F1, 0, 0, 0); @@ -8022,7 +8021,7 @@ static void test_accelerators(void) keybd_event(VK_F10, 0, 0, 0); keybd_event(VK_F10, 0, KEYEVENTF_KEYUP, 0); pump_msg_loop(hwnd, 0); - ok_sequence(WmVkF10Seq, "VK_F10 press/release", TRUE); + ok_sequence(WmVkF10Seq, "VK_F10 press/release", FALSE); trace("testing SHIFT+F10 press/release\n"); keybd_event(VK_SHIFT, 0, 0, 0); diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 0de7955..938e57f 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2757,17 +2757,6 @@ LRESULT CDECL X11DRV_SysCommand( HWND hwnd, WPARAM wparam, LPARAM lparam ) default: dir = _NET_WM_MOVERESIZE_SIZE_KEYBOARD; break; } break; - - case SC_KEYMENU: - /* prevent a simple ALT press+release from activating the system menu, - * as that can get confusing on managed windows */ - if ((WCHAR)lparam) goto failed; /* got an explicit char */ - if (GetMenu( hwnd )) goto failed; /* window has a real menu */ - if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_SYSMENU)) goto failed; /* no system menu */ - TRACE( "ignoring SC_KEYMENU wp %lx lp %lx\n", wparam, lparam ); - release_win_data( data ); - return 0; - default: goto failed; } -- 2.10.0 From hverbeet at codeweavers.com Tue Oct 11 06:40:20 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Tue, 11 Oct 2016 13:40:20 +0200 Subject: [PATCH] d2d1: Make some of drawing calls a wrappers over DrawGeometry() In-Reply-To: <20161010142956.12746-1-nsivov@codeweavers.com> References: <20161010142956.12746-1-nsivov@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Tue Oct 11 06:40:19 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Tue, 11 Oct 2016 13:40:19 +0200 Subject: [v3 PATCH] d2d1: Support shared bitmaps created from dxgi surface In-Reply-To: <20161010141239.12128-1-nsivov@codeweavers.com> References: <20161010141239.12128-1-nsivov@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From huw at codeweavers.com Tue Oct 11 07:01:09 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 11 Oct 2016 13:01:09 +0100 Subject: [PATCH 1/4] wordpad: Switch the main menu to MENUEX so that the list menu can be given an id. Message-ID: <1476187272-65734-1-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- programs/wordpad/wordpad.h | 1 + programs/wordpad/wordpad.rc | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/programs/wordpad/wordpad.h b/programs/wordpad/wordpad.h index 901b19c..0baf8c9 100644 --- a/programs/wordpad/wordpad.h +++ b/programs/wordpad/wordpad.h @@ -80,6 +80,7 @@ #define ID_UCLETTER 1318 #define ID_LCROMAN 1319 #define ID_UCROMAN 1320 +#define ID_LISTMENU 1325 #define ID_FONTSETTINGS 1330 diff --git a/programs/wordpad/wordpad.rc b/programs/wordpad/wordpad.rc index 147beea..368d169 100644 --- a/programs/wordpad/wordpad.rc +++ b/programs/wordpad/wordpad.rc @@ -23,7 +23,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT -IDM_MAINMENU MENU +IDM_MAINMENU MENUEX BEGIN POPUP "&File" BEGIN @@ -81,17 +81,17 @@ BEGIN POPUP "F&ormat" BEGIN MENUITEM "&Font...", ID_FONTSETTINGS - POPUP "&Lists" + POPUP "&Lists", ID_LISTMENU BEGIN - MENUITEM "&Bullet points" ID_BULLET - MENUITEM "Numbers" ID_NUMBERING - MENUITEM "Letters - lower case" ID_LCLETTER - MENUITEM "Letters - upper case" ID_UCLETTER - MENUITEM "Roman numerals - lower case" ID_LCROMAN - MENUITEM "Roman numerals - upper case" ID_UCROMAN + MENUITEM "&Bullet points", ID_BULLET + MENUITEM "Numbers", ID_NUMBERING + MENUITEM "Letters - lower case", ID_LCLETTER + MENUITEM "Letters - upper case", ID_UCLETTER + MENUITEM "Roman numerals - lower case", ID_LCROMAN + MENUITEM "Roman numerals - upper case", ID_UCROMAN END - MENUITEM "&Paragraph..." ID_PARAFORMAT - MENUITEM "&Tabs..." ID_TABSTOPS + MENUITEM "&Paragraph...", ID_PARAFORMAT + MENUITEM "&Tabs...", ID_TABSTOPS POPUP "Backgroun&d" BEGIN MENUITEM "&System\tCtrl+1", ID_BACK_1 @@ -100,7 +100,7 @@ BEGIN END POPUP "&Help" BEGIN - MENUITEM "&About Wine Wordpad" ID_ABOUT + MENUITEM "&About Wine Wordpad", ID_ABOUT END END -- 2.8.2 From huw at codeweavers.com Tue Oct 11 07:01:10 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 11 Oct 2016 13:01:10 +0100 Subject: [PATCH 2/4] wordpad: Remove BTNS_BUTTON from the toolbar style - it's a button style. Message-ID: <1476187272-65734-2-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- programs/wordpad/wordpad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/wordpad/wordpad.c b/programs/wordpad/wordpad.c index dc3918e..a26faab 100644 --- a/programs/wordpad/wordpad.c +++ b/programs/wordpad/wordpad.c @@ -1814,7 +1814,7 @@ static LRESULT OnCreate( HWND hWnd ) if(!SendMessageW(hReBarWnd, RB_SETBARINFO, 0, (LPARAM)&rbi)) return -1; - hToolBarWnd = CreateToolbarEx(hReBarWnd, CCS_NOPARENTALIGN|CCS_NOMOVEY|WS_VISIBLE|WS_CHILD|TBSTYLE_TOOLTIPS|BTNS_BUTTON, + hToolBarWnd = CreateToolbarEx(hReBarWnd, CCS_NOPARENTALIGN|CCS_NOMOVEY|WS_VISIBLE|WS_CHILD|TBSTYLE_TOOLTIPS, IDC_TOOLBAR, 1, hInstance, IDB_TOOLBAR, NULL, 0, @@ -1876,7 +1876,7 @@ static LRESULT OnCreate( HWND hWnd ) SendMessageW(hReBarWnd, RB_INSERTBANDW, -1, (LPARAM)&rbb); hFormatBarWnd = CreateToolbarEx(hReBarWnd, - CCS_NOPARENTALIGN | CCS_NOMOVEY | WS_VISIBLE | TBSTYLE_TOOLTIPS | BTNS_BUTTON, + CCS_NOPARENTALIGN | CCS_NOMOVEY | WS_VISIBLE | TBSTYLE_TOOLTIPS, IDC_FORMATBAR, 8, hInstance, IDB_FORMATBAR, NULL, 0, 16, 16, 16, 16, sizeof(TBBUTTON)); AddButton(hFormatBarWnd, 0, ID_FORMAT_BOLD); -- 2.8.2 From huw at codeweavers.com Tue Oct 11 07:01:11 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 11 Oct 2016 13:01:11 +0100 Subject: [PATCH 3/4] wordpad: Add a dropdown menu to the bullet button. Message-ID: <1476187272-65734-3-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- programs/wordpad/wordpad.c | 66 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/programs/wordpad/wordpad.c b/programs/wordpad/wordpad.c index a26faab..be5f6c2 100644 --- a/programs/wordpad/wordpad.c +++ b/programs/wordpad/wordpad.c @@ -156,7 +156,7 @@ static int MessageBoxWithResStringW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption } -static void AddButton(HWND hwndToolBar, int nImage, int nCommand) +static void AddButtonStyle(HWND hwndToolBar, int nImage, int nCommand, BYTE style) { TBBUTTON button; @@ -164,12 +164,17 @@ static void AddButton(HWND hwndToolBar, int nImage, int nCommand) button.iBitmap = nImage; button.idCommand = nCommand; button.fsState = TBSTATE_ENABLED; - button.fsStyle = BTNS_BUTTON; + button.fsStyle = style; button.dwData = 0; button.iString = -1; SendMessageW(hwndToolBar, TB_ADDBUTTONSW, 1, (LPARAM)&button); } +static void AddButton(HWND hwndToolBar, int nImage, int nCommand) +{ + AddButtonStyle(hwndToolBar, nImage, nCommand, BTNS_BUTTON); +} + static void AddSeparator(HWND hwndToolBar) { TBBUTTON button; @@ -1879,6 +1884,8 @@ static LRESULT OnCreate( HWND hWnd ) CCS_NOPARENTALIGN | CCS_NOMOVEY | WS_VISIBLE | TBSTYLE_TOOLTIPS, IDC_FORMATBAR, 8, hInstance, IDB_FORMATBAR, NULL, 0, 16, 16, 16, 16, sizeof(TBBUTTON)); + SendMessageW(hFormatBarWnd, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS); + AddButton(hFormatBarWnd, 0, ID_FORMAT_BOLD); AddButton(hFormatBarWnd, 1, ID_FORMAT_ITALIC); AddButton(hFormatBarWnd, 2, ID_FORMAT_UNDERLINE); @@ -1888,7 +1895,7 @@ static LRESULT OnCreate( HWND hWnd ) AddButton(hFormatBarWnd, 5, ID_ALIGN_CENTER); AddButton(hFormatBarWnd, 6, ID_ALIGN_RIGHT); AddSeparator(hFormatBarWnd); - AddButton(hFormatBarWnd, 7, ID_BULLETONOFF); + AddButtonStyle(hFormatBarWnd, 7, ID_BULLETONOFF, BTNS_DROPDOWN); SendMessageW(hFormatBarWnd, TB_AUTOSIZE, 0, 0); @@ -2007,6 +2014,7 @@ static LRESULT OnNotify( HWND hWnd, LPARAM lParam) NMHDR *pHdr = (NMHDR *)lParam; HWND hwndFontList = GetDlgItem(hwndReBar, IDC_FONTLIST); HWND hwndSizeList = GetDlgItem(hwndReBar, IDC_SIZELIST); + HWND hwndFormatBar = GetDlgItem(hwndReBar, IDC_FORMATBAR); if (pHdr->hwndFrom == hwndFontList || pHdr->hwndFrom == hwndSizeList) { @@ -2024,22 +2032,52 @@ static LRESULT OnNotify( HWND hWnd, LPARAM lParam) return 0; } - if (pHdr->hwndFrom != hwndEditor) + if (pHdr->hwndFrom == hwndFormatBar) + { + if (pHdr->code == TBN_DROPDOWN) + { + NMTOOLBARW *tb_notify = (NMTOOLBARW *)lParam; + HMENU menu = GetMenu( hWnd ); + MENUITEMINFOW info; + TPMPARAMS params; + BOOL ret; + RECT rc; + + if (!menu) return 0; + info.cbSize = sizeof(info); + info.fMask = MIIM_SUBMENU; + ret = GetMenuItemInfoW( menu, ID_LISTMENU, FALSE, &info ); + if (!info.hSubMenu) return 0; + + SendMessageW( tb_notify->hdr.hwndFrom, TB_GETRECT, (WPARAM)tb_notify->iItem, (LPARAM)&rc ); + MapWindowPoints( tb_notify->hdr.hwndFrom, HWND_DESKTOP, (LPPOINT)&rc, 2 ); + + params.cbSize = sizeof(params); + params.rcExclude = rc; + TrackPopupMenuEx( info.hSubMenu, + TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL, + rc.left, rc.bottom, hWnd, ¶ms ); + } + return 0; + } - if (pHdr->code == EN_SELCHANGE) + if (pHdr->hwndFrom == hwndEditor) { - SELCHANGE *pSC = (SELCHANGE *)lParam; - char buf[128]; + if (pHdr->code == EN_SELCHANGE) + { + SELCHANGE *pSC = (SELCHANGE *)lParam; + char buf[128]; - update_font_list(); + update_font_list(); - sprintf( buf,"selection = %d..%d, line count=%ld", - pSC->chrg.cpMin, pSC->chrg.cpMax, - SendMessageW(hwndEditor, EM_GETLINECOUNT, 0, 0)); - SetWindowTextA(GetDlgItem(hWnd, IDC_STATUSBAR), buf); - SendMessageW(hWnd, WM_USER, 0, 0); - return 1; + sprintf( buf,"selection = %d..%d, line count=%ld", + pSC->chrg.cpMin, pSC->chrg.cpMax, + SendMessageW(hwndEditor, EM_GETLINECOUNT, 0, 0)); + SetWindowTextA(GetDlgItem(hWnd, IDC_STATUSBAR), buf); + SendMessageW(hWnd, WM_USER, 0, 0); + return 1; + } } return 0; } -- 2.8.2 From huw at codeweavers.com Tue Oct 11 07:01:12 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 11 Oct 2016 13:01:12 +0100 Subject: [PATCH 4/4] wordpad: Keep the list indentation aligned when the margins are changed. Message-ID: <1476187272-65734-4-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- programs/wordpad/wordpad.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/programs/wordpad/wordpad.c b/programs/wordpad/wordpad.c index be5f6c2..01f36af 100644 --- a/programs/wordpad/wordpad.c +++ b/programs/wordpad/wordpad.c @@ -1579,8 +1579,15 @@ static INT_PTR CALLBACK paraformat_proc(HWND hWnd, UINT message, WPARAM wParam, int index; float num; int ret = 0; - PARAFORMAT pf; + PARAFORMAT2 pf; UNIT unit; + BOOL in_list = FALSE; + + pf.cbSize = sizeof(pf); + pf.dwMask = PFM_NUMBERING; + SendMessageW(hEditorWnd, EM_GETPARAFORMAT, 0, (LPARAM)&pf); + if ((pf.dwMask & PFM_NUMBERING) && pf.wNumbering) + in_list = TRUE; index = SendMessageW(hListWnd, CB_GETCURSEL, 0, 0); pf.wAlignment = ALIGNMENT_VALUES[index]; @@ -1630,6 +1637,12 @@ static INT_PTR CALLBACK paraformat_proc(HWND hWnd, UINT message, WPARAM wParam, pf.cbSize = sizeof(pf); pf.dwMask = PFM_ALIGNMENT | PFM_OFFSET | PFM_RIGHTINDENT | PFM_STARTINDENT; + if (in_list) + { + pf.wNumberingTab = max(pf.dxOffset, 0); + pf.dwMask |= PFM_NUMBERINGTAB; + } + SendMessageW(hEditorWnd, EM_SETPARAFORMAT, 0, (LPARAM)&pf); } } -- 2.8.2 From huw at codeweavers.com Tue Oct 11 07:04:00 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 11 Oct 2016 13:04:00 +0100 Subject: [PATCH 2/6] riched20: Don't emit paragraph props if they're the same as the previous paragraph's. Message-ID: <1476187444-65942-2-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/writer.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index 0204215..27e07b1 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -429,6 +429,10 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, PARAFORMAT2 *fmt = ¶->member.para.fmt; char props[STREAMOUT_BUFFER_SIZE] = ""; int i; + ME_Paragraph *prev_para = NULL; + + if (para->member.para.prev_para->type == diParagraph) + prev_para = ¶->member.para.prev_para->member.para; if (!editor->bEmulateVersion10) { /* v4.1 */ if (para->member.para.nFlags & MEPF_ROWSTART) { @@ -462,7 +466,9 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, } } - /* TODO: Don't emit anything if the last PARAFORMAT2 is inherited */ + if (prev_para && !memcmp( fmt, &prev_para->fmt, sizeof(*fmt) )) + return TRUE; + if (!ME_StreamOutPrint(pStream, "\\pard")) return FALSE; -- 2.8.2 From huw at codeweavers.com Tue Oct 11 07:03:59 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 11 Oct 2016 13:03:59 +0100 Subject: [PATCH 1/6] riched20: The new eop style when typing a list is a copy of the existing eop style. Message-ID: <1476187444-65942-1-git-send-email-huw@codeweavers.com> Normally the new eop style is the insert style, however in a list the existing eop style is used. This prevents the list label style from changing when the new eop is inserted. Signed-off-by: Huw Davies --- dlls/riched20/editor.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 162daa8..8b94ccf 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -2404,7 +2404,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) int from, to; const WCHAR endl = '\r'; const WCHAR endlv10[] = {'\r','\n'}; - ME_Style *style; + ME_Style *style, *eop_style; if (editor->styleFlags & ES_READONLY) { MessageBeep(MB_ICONERROR); @@ -2501,14 +2501,22 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) } style = ME_GetInsertStyle(editor, 0); + + /* Normally the new eop style is the insert style, however in a list it is copied from the existing + eop style (this prevents the list label style changing when the new eop is inserted). + No extra ref is taken here on eop_style. */ + if (para->member.para.fmt.wNumbering) + eop_style = para->member.para.eop_run->style; + else + eop_style = style; ME_ContinueCoalescingTransaction(editor); if (shift_is_down) ME_InsertEndRowFromCursor(editor, 0); else if (!editor->bEmulateVersion10) - ME_InsertTextFromCursor(editor, 0, &endl, 1, style); + ME_InsertTextFromCursor(editor, 0, &endl, 1, eop_style); else - ME_InsertTextFromCursor(editor, 0, endlv10, 2, style); + ME_InsertTextFromCursor(editor, 0, endlv10, 2, eop_style); ME_CommitCoalescingUndo(editor); SetCursor(NULL); -- 2.8.2 From huw at codeweavers.com Tue Oct 11 07:04:01 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 11 Oct 2016 13:04:01 +0100 Subject: [PATCH 3/6] riched20: Don't emit default values. Message-ID: <1476187444-65942-3-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/writer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index 27e07b1..a2ec8f8 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -549,11 +549,11 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, if (!(editor->bEmulateVersion10 && /* v1.0 - 3.0 */ fmt->dwMask & PFM_TABLE && fmt->wEffects & PFE_TABLE)) { - if (fmt->dwMask & PFM_OFFSET) + if (fmt->dxOffset) sprintf(props + strlen(props), "\\li%d", fmt->dxOffset); - if (fmt->dwMask & PFM_OFFSETINDENT || fmt->dwMask & PFM_STARTINDENT) + if (fmt->dxStartIndent) sprintf(props + strlen(props), "\\fi%d", fmt->dxStartIndent); - if (fmt->dwMask & PFM_RIGHTINDENT) + if (fmt->dxRightIndent) sprintf(props + strlen(props), "\\ri%d", fmt->dxRightIndent); if (fmt->dwMask & PFM_TABSTOPS) { static const char * const leader[6] = { "", "\\tldot", "\\tlhyph", "\\tlul", "\\tlth", "\\tleq" }; @@ -579,11 +579,11 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, } } } - if (fmt->dwMask & PFM_SPACEAFTER) + if (fmt->dySpaceAfter) sprintf(props + strlen(props), "\\sa%d", fmt->dySpaceAfter); - if (fmt->dwMask & PFM_SPACEBEFORE) + if (fmt->dySpaceBefore) sprintf(props + strlen(props), "\\sb%d", fmt->dySpaceBefore); - if (fmt->dwMask & PFM_STYLE) + if (fmt->sStyle != -1) sprintf(props + strlen(props), "\\s%d", fmt->sStyle); if (fmt->dwMask & PFM_SHADING) { -- 2.8.2 From huw at codeweavers.com Tue Oct 11 07:04:02 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 11 Oct 2016 13:04:02 +0100 Subject: [PATCH 4/6] riched20: Add a helper to add a font to the font table. Message-ID: <1476187444-65942-4-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/writer.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index a2ec8f8..b448f43 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -213,6 +213,29 @@ ME_StreamOutRTFHeader(ME_OutStream *pStream, int dwFormat) return TRUE; } +static void add_font_to_fonttbl( ME_OutStream *stream, ME_Style *style ) +{ + ME_FontTableItem *table = stream->fonttbl; + CHARFORMAT2W *fmt = &style->fmt; + WCHAR *face = fmt->szFaceName; + BYTE charset = (fmt->dwMask & CFM_CHARSET) ? fmt->bCharSet : DEFAULT_CHARSET; + int i; + + if (fmt->dwMask & CFM_FACE) + { + for (i = 0; i < stream->nFontTblLen; i++) + if (table[i].bCharSet == charset + && (table[i].szFaceName == face || !lstrcmpW(table[i].szFaceName, face))) + break; + + if (i == stream->nFontTblLen && i < STREAMOUT_FONTTBL_SIZE) + { + table[i].bCharSet = charset; + table[i].szFaceName = face; + stream->nFontTblLen++; + } + } +} static BOOL ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, @@ -223,26 +246,13 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, unsigned int i; ME_DisplayItem *pLastPara = ME_GetParagraph(pLastRun); ME_DisplayItem *pCell = NULL; - + do { CHARFORMAT2W *fmt = &item->member.run.style->fmt; COLORREF crColor; - if (fmt->dwMask & CFM_FACE) { - WCHAR *face = fmt->szFaceName; - BYTE bCharSet = (fmt->dwMask & CFM_CHARSET) ? fmt->bCharSet : DEFAULT_CHARSET; - - for (i = 0; i < pStream->nFontTblLen; i++) - if (table[i].bCharSet == bCharSet - && (table[i].szFaceName == face || !lstrcmpW(table[i].szFaceName, face))) - break; - if (i == pStream->nFontTblLen && i < STREAMOUT_FONTTBL_SIZE) { - table[i].bCharSet = bCharSet; - table[i].szFaceName = face; - pStream->nFontTblLen++; - } - } - + add_font_to_fonttbl( pStream, item->member.run.style ); + if (fmt->dwMask & CFM_COLOR && !(fmt->dwEffects & CFE_AUTOCOLOR)) { crColor = fmt->crTextColor; for (i = 1; i < pStream->nColorTblLen; i++) -- 2.8.2 From huw at codeweavers.com Tue Oct 11 07:04:03 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 11 Oct 2016 13:04:03 +0100 Subject: [PATCH 5/6] riched20: Add a helper to add a colour to the colour table. Message-ID: <1476187444-65942-5-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/writer.c | 54 +++++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index b448f43..e79aacf 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -237,6 +237,21 @@ static void add_font_to_fonttbl( ME_OutStream *stream, ME_Style *style ) } } +static void add_color_to_colortbl( ME_OutStream *stream, COLORREF color ) +{ + int i; + + for (i = 1; i < stream->nColorTblLen; i++) + if (stream->colortbl[i] == color) + break; + + if (i == stream->nColorTblLen && i < STREAMOUT_COLORTBL_SIZE) + { + stream->colortbl[i] = color; + stream->nColorTblLen++; + } +} + static BOOL ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, ME_DisplayItem *pLastRun) @@ -249,30 +264,13 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, do { CHARFORMAT2W *fmt = &item->member.run.style->fmt; - COLORREF crColor; add_font_to_fonttbl( pStream, item->member.run.style ); - if (fmt->dwMask & CFM_COLOR && !(fmt->dwEffects & CFE_AUTOCOLOR)) { - crColor = fmt->crTextColor; - for (i = 1; i < pStream->nColorTblLen; i++) - if (pStream->colortbl[i] == crColor) - break; - if (i == pStream->nColorTblLen && i < STREAMOUT_COLORTBL_SIZE) { - pStream->colortbl[i] = crColor; - pStream->nColorTblLen++; - } - } - if (fmt->dwMask & CFM_BACKCOLOR && !(fmt->dwEffects & CFE_AUTOBACKCOLOR)) { - crColor = fmt->crBackColor; - for (i = 1; i < pStream->nColorTblLen; i++) - if (pStream->colortbl[i] == crColor) - break; - if (i == pStream->nColorTblLen && i < STREAMOUT_COLORTBL_SIZE) { - pStream->colortbl[i] = crColor; - pStream->nColorTblLen++; - } - } + if (fmt->dwMask & CFM_COLOR && !(fmt->dwEffects & CFE_AUTOCOLOR)) + add_color_to_colortbl( pStream, fmt->crTextColor ); + if (fmt->dwMask & CFM_BACKCOLOR && !(fmt->dwEffects & CFE_AUTOBACKCOLOR)) + add_color_to_colortbl( pStream, fmt->crBackColor ); if (item == pLastRun) break; @@ -287,20 +285,8 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, &pCell->member.cell.border.bottom, &pCell->member.cell.border.right }; for (i = 0; i < 4; i++) - { if (borders[i]->width > 0) - { - unsigned int j; - COLORREF crColor = borders[i]->colorRef; - for (j = 1; j < pStream->nColorTblLen; j++) - if (pStream->colortbl[j] == crColor) - break; - if (j == pStream->nColorTblLen && j < STREAMOUT_COLORTBL_SIZE) { - pStream->colortbl[j] = crColor; - pStream->nColorTblLen++; - } - } - } + add_color_to_colortbl( pStream, borders[i]->colorRef ); } if (item == pLastPara) break; -- 2.8.2 From huw at codeweavers.com Tue Oct 11 07:04:04 2016 From: huw at codeweavers.com (Huw Davies) Date: Tue, 11 Oct 2016 13:04:04 +0100 Subject: [PATCH 6/6] riched20: Move the check for cell border colours into the same loop as the other colours. Message-ID: <1476187444-65942-6-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/writer.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index e79aacf..fe8c797 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -259,8 +259,8 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, ME_DisplayItem *item = pFirstRun; ME_FontTableItem *table = pStream->fonttbl; unsigned int i; - ME_DisplayItem *pLastPara = ME_GetParagraph(pLastRun); ME_DisplayItem *pCell = NULL; + ME_Paragraph *prev_para = NULL; do { CHARFORMAT2W *fmt = &item->member.run.style->fmt; @@ -272,14 +272,10 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, if (fmt->dwMask & CFM_BACKCOLOR && !(fmt->dwEffects & CFE_AUTOBACKCOLOR)) add_color_to_colortbl( pStream, fmt->crBackColor ); - if (item == pLastRun) - break; - item = ME_FindItemFwd(item, diRun); - } while (item); - item = ME_GetParagraph(pFirstRun); - do { - if ((pCell = item->member.para.pCell)) + if (item->member.run.para != prev_para) { + if ((pCell = item->member.para.pCell)) + { ME_Border* borders[4] = { &pCell->member.cell.border.top, &pCell->member.cell.border.left, &pCell->member.cell.border.bottom, @@ -287,12 +283,16 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, for (i = 0; i < 4; i++) if (borders[i]->width > 0) add_color_to_colortbl( pStream, borders[i]->colorRef ); + } + + prev_para = item->member.run.para; } - if (item == pLastPara) + + if (item == pLastRun) break; - item = item->member.para.next_para; + item = ME_FindItemFwd(item, diRun); } while (item); - + if (!ME_StreamOutPrint(pStream, "{\\fonttbl")) return FALSE; -- 2.8.2 From sebastian at fds-team.de Tue Oct 11 07:09:35 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Tue, 11 Oct 2016 14:09:35 +0200 Subject: [1/2] winebus.sys: Implement IOCTL_HID_GET_DEVICE_DESCRIPTOR for hidraw. (v3) Message-ID: <13a98311-0cd0-c627-2c13-246090bc07c5@fds-team.de> From: Aric Stewart Signed-off-by: Aric Stewart Signed-off-by: Sebastian Lackner --- Changes in v3: * Remove autogenerated changes from patch. * Do not rely on "length" not changing in call, instead explicitly check status. * Change "length" to unsigned types (like in the Windows and Linux structures). * Rename "extension" -> "ext" for consistency reasons. * Use "private" instead of "ext" when referring to platform private data pointers. * Some style fixes. configure.ac | 1 dlls/winebus.sys/bus.h | 1 dlls/winebus.sys/bus_udev.c | 53 +++++++++++++++++++++++++++++++++++++++++--- dlls/winebus.sys/main.c | 46 +++++++++++++++++++++++++++++++++----- 4 files changed, 92 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 741a4ef..eb328a0 100644 --- a/configure.ac +++ b/configure.ac @@ -426,6 +426,7 @@ AC_CHECK_HEADERS(\ linux/compiler.h \ linux/filter.h \ linux/hdreg.h \ + linux/hidraw.h \ linux/input.h \ linux/ioctl.h \ linux/joystick.h \ diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index 342a66b..9ab242c 100644 --- a/dlls/winebus.sys/bus.h +++ b/dlls/winebus.sys/bus.h @@ -23,6 +23,7 @@ NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry typedef struct { int (*compare_platform_device)(DEVICE_OBJECT *device, void *platform_dev); + NTSTATUS (*get_reportdescriptor)(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length); } platform_vtbl; void *get_platform_private(DEVICE_OBJECT *device) DECLSPEC_HIDDEN; diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index a01d88e..22ea07d 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -35,6 +35,12 @@ #ifdef HAVE_LIBUDEV_H # include #endif +#ifdef HAVE_LINUX_HIDRAW_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif #define NONAMELESSUNION @@ -64,6 +70,7 @@ DEFINE_GUID(GUID_DEVCLASS_HIDRAW, 0x3def44ad,0x242e,0x46e5,0x82,0x6d,0x70,0x72,0 struct platform_private { struct udev_device *udev_device; + int device_fd; }; static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device) @@ -105,9 +112,42 @@ static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev) return strcmp(udev_device_get_syspath(dev1), udev_device_get_syspath(dev2)); } +static NTSTATUS hidraw_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length) +{ +#ifdef HAVE_LINUX_HIDRAW_H + struct hidraw_report_descriptor descriptor; + struct platform_private *private = impl_from_DEVICE_OBJECT(device); + + if (ioctl(private->device_fd, HIDIOCGRDESCSIZE, &descriptor.size) == -1) + { + WARN("ioctl(HIDIOCGRDESCSIZE) failed: %d %s\n", errno, strerror(errno)); + return STATUS_UNSUCCESSFUL; + } + + *out_length = descriptor.size; + + if (length < descriptor.size) + return STATUS_BUFFER_TOO_SMALL; + if (!descriptor.size) + return STATUS_SUCCESS; + + if (ioctl(private->device_fd, HIDIOCGRDESC, &descriptor) == -1) + { + WARN("ioctl(HIDIOCGRDESC) failed: %d %s\n", errno, strerror(errno)); + return STATUS_UNSUCCESSFUL; + } + + memcpy(buffer, descriptor.value, descriptor.size); + return STATUS_SUCCESS; +#else + return STATUS_NOT_IMPLEMENTED; +#endif +} + static const platform_vtbl hidraw_vtbl = { compare_platform_device, + hidraw_get_reportdescriptor, }; static void try_add_device(struct udev_device *dev) @@ -128,7 +168,6 @@ static void try_add_device(struct udev_device *dev) WARN("Unable to open udev device %s: %s\n", debugstr_a(devnode), strerror(errno)); return; } - close(fd); usbdev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"); if (usbdev) @@ -151,11 +190,16 @@ static void try_add_device(struct udev_device *dev) if (device) { - impl_from_DEVICE_OBJECT(device)->udev_device = udev_device_ref(dev); + struct platform_private *private = impl_from_DEVICE_OBJECT(device); + private->udev_device = udev_device_ref(dev); + private->device_fd = fd; IoInvalidateDeviceRelations(device, BusRelations); } else + { WARN("Ignoring device %s with subsystem %s\n", debugstr_a(devnode), subsystem); + close(fd); + } HeapFree(GetProcessHeap(), 0, serial); } @@ -163,9 +207,12 @@ static void try_add_device(struct udev_device *dev) static void try_remove_device(struct udev_device *dev) { DEVICE_OBJECT *device = bus_find_hid_device(&hidraw_vtbl, dev); + struct platform_private *private; if (!device) return; - dev = impl_from_DEVICE_OBJECT(device)->udev_device; + private = impl_from_DEVICE_OBJECT(device); + dev = private->udev_device; + close(private->device_fd); bus_remove_hid_device(device); udev_device_unref(dev); } diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index eaa0b93..bf7071d 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -352,7 +352,7 @@ NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp) { NTSTATUS status = irp->IoStatus.u.Status; IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); - struct device_extension *extension = (struct device_extension *)device->DeviceExtension; + struct device_extension *ext = (struct device_extension *)device->DeviceExtension; TRACE("(%p, %p)\n", device, irp); @@ -370,12 +370,46 @@ NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp) } memset(attr, 0, sizeof(*attr)); - attr->Size = sizeof(HID_DEVICE_ATTRIBUTES); - attr->VendorID = extension->vid; - attr->ProductID = extension->pid; - attr->VersionNumber = extension->version; + attr->Size = sizeof(*attr); + attr->VendorID = ext->vid; + attr->ProductID = ext->pid; + attr->VersionNumber = ext->version; + + irp->IoStatus.u.Status = status = STATUS_SUCCESS; + irp->IoStatus.Information = sizeof(*attr); + break; + } + case IOCTL_HID_GET_DEVICE_DESCRIPTOR: + { + HID_DESCRIPTOR *descriptor = (HID_DESCRIPTOR *)irp->UserBuffer; + DWORD length; + TRACE("IOCTL_HID_GET_DEVICE_DESCRIPTOR\n"); + + if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*descriptor)) + { + irp->IoStatus.u.Status = status = STATUS_BUFFER_TOO_SMALL; + break; + } + + status = ext->vtbl->get_reportdescriptor(device, NULL, 0, &length); + if (status != STATUS_SUCCESS && status != STATUS_BUFFER_TOO_SMALL) + { + WARN("Failed to get platform report descriptor length\n"); + irp->IoStatus.u.Status = status; + break; + } + + memset(descriptor, 0, sizeof(*descriptor)); + descriptor->bLength = sizeof(*descriptor); + descriptor->bDescriptorType = HID_HID_DESCRIPTOR_TYPE; + descriptor->bcdHID = HID_REVISION; + descriptor->bCountry = 0; + descriptor->bNumDescriptors = 1; + descriptor->DescriptorList[0].bReportType = HID_REPORT_DESCRIPTOR_TYPE; + descriptor->DescriptorList[0].wReportLength = length; + irp->IoStatus.u.Status = status = STATUS_SUCCESS; - irp->IoStatus.Information = sizeof(HID_DEVICE_ATTRIBUTES); + irp->IoStatus.Information = sizeof(*descriptor); break; } default: -- 2.9.0 From sebastian at fds-team.de Tue Oct 11 07:09:46 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Tue, 11 Oct 2016 14:09:46 +0200 Subject: [2/2] winebus.sys: Implement IOCTL_HID_GET_REPORT_DESCRIPTOR for hidraw. (v3) Message-ID: From: Aric Stewart Signed-off-by: Aric Stewart Signed-off-by: Sebastian Lackner --- Changes in v3: * Avoid extremely long line. ;) dlls/winebus.sys/main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index bf7071d..ad09ec1 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -412,6 +412,15 @@ NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp) irp->IoStatus.Information = sizeof(*descriptor); break; } + case IOCTL_HID_GET_REPORT_DESCRIPTOR: + { + DWORD length = irpsp->Parameters.DeviceIoControl.OutputBufferLength; + TRACE("IOCTL_HID_GET_REPORT_DESCRIPTOR\n"); + + irp->IoStatus.u.Status = status = ext->vtbl->get_reportdescriptor(device, irp->UserBuffer, length, &length); + irp->IoStatus.Information = length; + break; + } default: { ULONG code = irpsp->Parameters.DeviceIoControl.IoControlCode; -- 2.9.0 From nsivov at codeweavers.com Tue Oct 11 07:20:26 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Tue, 11 Oct 2016 15:20:26 +0300 Subject: [PATCH] dwrite: Update to IDWriteFactory4 Message-ID: <20161011122026.980-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/dwrite/analyzer.c | 10 +- dlls/dwrite/dwrite_private.h | 22 ++-- dlls/dwrite/font.c | 46 ++++---- dlls/dwrite/gdiinterop.c | 12 +- dlls/dwrite/layout.c | 14 +-- dlls/dwrite/main.c | 265 ++++++++++++++++++++++++------------------- 6 files changed, 203 insertions(+), 166 deletions(-) diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c index 745dc6a..3f146c5 100644 --- a/dlls/dwrite/analyzer.c +++ b/dlls/dwrite/analyzer.c @@ -193,7 +193,7 @@ static const struct fallback_mapping fontfallback_neutral_data[] = { struct dwrite_fontfallback { IDWriteFontFallback IDWriteFontFallback_iface; - IDWriteFactory3 *factory; + IDWriteFactory4 *factory; IDWriteFontCollection1 *systemcollection; const struct fallback_mapping *mappings; UINT32 count; @@ -1785,14 +1785,14 @@ static ULONG WINAPI fontfallback_AddRef(IDWriteFontFallback *iface) { struct dwrite_fontfallback *fallback = impl_from_IDWriteFontFallback(iface); TRACE("(%p)\n", fallback); - return IDWriteFactory3_AddRef(fallback->factory); + return IDWriteFactory4_AddRef(fallback->factory); } static ULONG WINAPI fontfallback_Release(IDWriteFontFallback *iface) { struct dwrite_fontfallback *fallback = impl_from_IDWriteFontFallback(iface); TRACE("(%p)\n", fallback); - return IDWriteFactory3_Release(fallback->factory); + return IDWriteFactory4_Release(fallback->factory); } static int compare_fallback_mapping(const void *a, const void *b) @@ -1968,7 +1968,7 @@ static const IDWriteFontFallbackVtbl fontfallbackvtbl = { fontfallback_MapCharacters }; -HRESULT create_system_fontfallback(IDWriteFactory3 *factory, IDWriteFontFallback **ret) +HRESULT create_system_fontfallback(IDWriteFactory4 *factory, IDWriteFontFallback **ret) { struct dwrite_fontfallback *fallback; @@ -1982,7 +1982,7 @@ HRESULT create_system_fontfallback(IDWriteFactory3 *factory, IDWriteFontFallback fallback->factory = factory; fallback->mappings = fontfallback_neutral_data; fallback->count = sizeof(fontfallback_neutral_data)/sizeof(fontfallback_neutral_data[0]); - IDWriteFactory3_GetSystemFontCollection(fallback->factory, FALSE, &fallback->systemcollection, FALSE); + IDWriteFactory4_GetSystemFontCollection(fallback->factory, FALSE, &fallback->systemcollection, FALSE); *ret = &fallback->IDWriteFontFallback_iface; return S_OK; diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 038efee..cf305e6 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -121,12 +121,12 @@ static inline BOOL is_simulation_valid(DWRITE_FONT_SIMULATIONS simulations) struct gdiinterop { IDWriteGdiInterop1 IDWriteGdiInterop1_iface; - IDWriteFactory3 *factory; + IDWriteFactory4 *factory; }; struct textlayout_desc { - IDWriteFactory3 *factory; + IDWriteFactory4 *factory; const WCHAR *string; UINT32 length; IDWriteTextFormat *format; @@ -154,7 +154,7 @@ struct glyphrunanalysis_desc struct fontface_desc { - IDWriteFactory3 *factory; + IDWriteFactory4 *factory; DWRITE_FONT_FACE_TYPE face_type; IDWriteFontFile * const *files; UINT32 files_number; @@ -168,20 +168,20 @@ extern HRESULT create_numbersubstitution(DWRITE_NUMBER_SUBSTITUTION_METHOD,const extern HRESULT create_textformat(const WCHAR*,IDWriteFontCollection*,DWRITE_FONT_WEIGHT,DWRITE_FONT_STYLE,DWRITE_FONT_STRETCH, FLOAT,const WCHAR*,IDWriteTextFormat**) DECLSPEC_HIDDEN; extern HRESULT create_textlayout(const struct textlayout_desc*,IDWriteTextLayout**) DECLSPEC_HIDDEN; -extern HRESULT create_trimmingsign(IDWriteFactory3*,IDWriteTextFormat*,IDWriteInlineObject**) DECLSPEC_HIDDEN; +extern HRESULT create_trimmingsign(IDWriteFactory4*,IDWriteTextFormat*,IDWriteInlineObject**) DECLSPEC_HIDDEN; extern HRESULT create_typography(IDWriteTypography**) DECLSPEC_HIDDEN; -extern void gdiinterop_init(struct gdiinterop*,IDWriteFactory3*) DECLSPEC_HIDDEN; +extern void gdiinterop_init(struct gdiinterop*,IDWriteFactory4*) DECLSPEC_HIDDEN; extern HRESULT create_localizedstrings(IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN; extern HRESULT clone_localizedstring(IDWriteLocalizedStrings *iface, IDWriteLocalizedStrings **strings) DECLSPEC_HIDDEN; extern void set_en_localizedstring(IDWriteLocalizedStrings*,const WCHAR*) DECLSPEC_HIDDEN; -extern HRESULT get_system_fontcollection(IDWriteFactory3*,IDWriteFontCollection1**) DECLSPEC_HIDDEN; -extern HRESULT get_eudc_fontcollection(IDWriteFactory3*,IDWriteFontCollection**) DECLSPEC_HIDDEN; +extern HRESULT get_system_fontcollection(IDWriteFactory4*,IDWriteFontCollection1**) DECLSPEC_HIDDEN; +extern HRESULT get_eudc_fontcollection(IDWriteFactory4*,IDWriteFontCollection**) DECLSPEC_HIDDEN; extern HRESULT get_textanalyzer(IDWriteTextAnalyzer**) DECLSPEC_HIDDEN; extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN; extern HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface) DECLSPEC_HIDDEN; extern HRESULT create_fontface(const struct fontface_desc*,IDWriteFontFace3**) DECLSPEC_HIDDEN; -extern HRESULT create_font_collection(IDWriteFactory3*,IDWriteFontFileEnumerator*,BOOL,IDWriteFontCollection1**) DECLSPEC_HIDDEN; +extern HRESULT create_font_collection(IDWriteFactory4*,IDWriteFontFileEnumerator*,BOOL,IDWriteFontCollection1**) DECLSPEC_HIDDEN; extern HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc*,IDWriteGlyphRunAnalysis**) DECLSPEC_HIDDEN; extern BOOL is_system_collection(IDWriteFontCollection*) DECLSPEC_HIDDEN; extern HRESULT get_local_refkey(const WCHAR*,const FILETIME*,void**,UINT32*) DECLSPEC_HIDDEN; @@ -191,13 +191,13 @@ extern HRESULT get_family_names_from_stream(IDWriteFontFileStream*,UINT32,DWRITE extern HRESULT create_colorglyphenum(FLOAT,FLOAT,const DWRITE_GLYPH_RUN*,const DWRITE_GLYPH_RUN_DESCRIPTION*,DWRITE_MEASURING_MODE, const DWRITE_MATRIX*,UINT32,IDWriteColorGlyphRunEnumerator**) DECLSPEC_HIDDEN; extern BOOL lb_is_newline_char(WCHAR) DECLSPEC_HIDDEN; -extern HRESULT create_system_fontfallback(IDWriteFactory3*,IDWriteFontFallback**) DECLSPEC_HIDDEN; +extern HRESULT create_system_fontfallback(IDWriteFactory4*,IDWriteFontFallback**) DECLSPEC_HIDDEN; extern void release_system_fontfallback(IDWriteFontFallback*) DECLSPEC_HIDDEN; extern HRESULT create_matching_font(IDWriteFontCollection*,const WCHAR*,DWRITE_FONT_WEIGHT,DWRITE_FONT_STYLE,DWRITE_FONT_STRETCH, IDWriteFont**) DECLSPEC_HIDDEN; -extern HRESULT create_fontfacereference(IDWriteFactory3*,IDWriteFontFile*,UINT32,DWRITE_FONT_SIMULATIONS, +extern HRESULT create_fontfacereference(IDWriteFactory4*,IDWriteFontFile*,UINT32,DWRITE_FONT_SIMULATIONS, IDWriteFontFaceReference**) DECLSPEC_HIDDEN; -extern HRESULT factory_get_cached_fontface(IDWriteFactory3*,IDWriteFontFile*const*,UINT32,DWRITE_FONT_SIMULATIONS,IDWriteFontFace**, +extern HRESULT factory_get_cached_fontface(IDWriteFactory4*,IDWriteFontFile*const*,UINT32,DWRITE_FONT_SIMULATIONS,IDWriteFontFace**, struct list**) DECLSPEC_HIDDEN; extern void factory_cache_fontface(struct list*,IDWriteFontFace3*) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index e529d6f..6b9ee66 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -81,7 +81,7 @@ struct dwrite_font_data { IDWriteLocalizedStrings *names; /* data needed to create fontface instance */ - IDWriteFactory3 *factory; + IDWriteFactory4 *factory; DWRITE_FONT_FACE_TYPE face_type; IDWriteFontFile *file; UINT32 face_index; @@ -258,7 +258,7 @@ struct dwrite_fontfacereference { IDWriteFontFile *file; UINT32 index; USHORT simulations; - IDWriteFactory3 *factory; + IDWriteFactory4 *factory; }; static inline struct dwrite_fontface *impl_from_IDWriteFontFace3(IDWriteFontFace3 *iface) @@ -414,7 +414,7 @@ static void release_font_data(struct dwrite_font_data *data) IDWriteLocalizedStrings_Release(data->names); IDWriteFontFile_Release(data->file); - IDWriteFactory3_Release(data->factory); + IDWriteFactory4_Release(data->factory); heap_free(data->facename); heap_free(data); } @@ -1589,7 +1589,7 @@ static HRESULT WINAPI dwritefont3_GetFontFaceReference(IDWriteFont3 *iface, IDWr TRACE("(%p)->(%p)\n", This, reference); - return IDWriteFactory3_CreateFontFaceReference_(This->data->factory, This->data->file, This->data->face_index, + return IDWriteFactory4_CreateFontFaceReference_(This->data->factory, This->data->file, This->data->face_index, This->data->simulations, reference); } @@ -3188,7 +3188,7 @@ static HRESULT init_font_data(const struct fontface_desc *desc, IDWriteLocalized data->bold_sim_tested = 0; data->oblique_sim_tested = 0; IDWriteFontFile_AddRef(data->file); - IDWriteFactory3_AddRef(data->factory); + IDWriteFactory4_AddRef(data->factory); stream_desc.stream = stream; stream_desc.face_type = desc->face_type; @@ -3243,7 +3243,7 @@ static HRESULT init_font_data_from_font(const struct dwrite_font_data *src, DWRI data->style = DWRITE_FONT_STYLE_OBLIQUE; memset(data->info_strings, 0, sizeof(data->info_strings)); data->names = NULL; - IDWriteFactory3_AddRef(data->factory); + IDWriteFactory4_AddRef(data->factory); IDWriteFontFile_AddRef(data->file); create_localizedstrings(&data->names); @@ -3499,7 +3499,7 @@ static void fontcollection_add_replacements(struct dwrite_fontcollection *collec RegCloseKey(hkey); } -HRESULT create_font_collection(IDWriteFactory3 *factory, IDWriteFontFileEnumerator *enumerator, BOOL is_system, +HRESULT create_font_collection(IDWriteFactory4 *factory, IDWriteFontFileEnumerator *enumerator, BOOL is_system, IDWriteFontCollection1 **ret) { struct fontfile_enum { @@ -3651,7 +3651,7 @@ struct system_fontfile_enumerator IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface; LONG ref; - IDWriteFactory3 *factory; + IDWriteFactory4 *factory; HKEY hkey; int index; }; @@ -3686,7 +3686,7 @@ static ULONG WINAPI systemfontfileenumerator_Release(IDWriteFontFileEnumerator * ULONG ref = InterlockedDecrement(&enumerator->ref); if (!ref) { - IDWriteFactory3_Release(enumerator->factory); + IDWriteFactory4_Release(enumerator->factory); RegCloseKey(enumerator->hkey); heap_free(enumerator); } @@ -3694,7 +3694,7 @@ static ULONG WINAPI systemfontfileenumerator_Release(IDWriteFontFileEnumerator * return ref; } -static HRESULT create_local_file_reference(IDWriteFactory3 *factory, const WCHAR *filename, IDWriteFontFile **file) +static HRESULT create_local_file_reference(IDWriteFactory4 *factory, const WCHAR *filename, IDWriteFontFile **file) { HRESULT hr; @@ -3707,10 +3707,10 @@ static HRESULT create_local_file_reference(IDWriteFactory3 *factory, const WCHAR strcatW(fullpathW, fontsW); strcatW(fullpathW, filename); - hr = IDWriteFactory3_CreateFontFileReference(factory, fullpathW, NULL, file); + hr = IDWriteFactory4_CreateFontFileReference(factory, fullpathW, NULL, file); } else - hr = IDWriteFactory3_CreateFontFileReference(factory, filename, NULL, file); + hr = IDWriteFactory4_CreateFontFileReference(factory, filename, NULL, file); return hr; } @@ -3798,7 +3798,7 @@ static const struct IDWriteFontFileEnumeratorVtbl systemfontfileenumeratorvtbl = systemfontfileenumerator_GetCurrentFontFile }; -static HRESULT create_system_fontfile_enumerator(IDWriteFactory3 *factory, IDWriteFontFileEnumerator **ret) +static HRESULT create_system_fontfile_enumerator(IDWriteFactory4 *factory, IDWriteFontFileEnumerator **ret) { struct system_fontfile_enumerator *enumerator; static const WCHAR fontslistW[] = { @@ -3817,11 +3817,11 @@ static HRESULT create_system_fontfile_enumerator(IDWriteFactory3 *factory, IDWri enumerator->ref = 1; enumerator->factory = factory; enumerator->index = -1; - IDWriteFactory3_AddRef(factory); + IDWriteFactory4_AddRef(factory); if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, fontslistW, 0, GENERIC_READ, &enumerator->hkey)) { ERR("failed to open fonts list key\n"); - IDWriteFactory3_Release(factory); + IDWriteFactory4_Release(factory); heap_free(enumerator); return E_FAIL; } @@ -3831,7 +3831,7 @@ static HRESULT create_system_fontfile_enumerator(IDWriteFactory3 *factory, IDWri return S_OK; } -HRESULT get_system_fontcollection(IDWriteFactory3 *factory, IDWriteFontCollection1 **collection) +HRESULT get_system_fontcollection(IDWriteFactory4 *factory, IDWriteFontCollection1 **collection) { IDWriteFontFileEnumerator *enumerator; HRESULT hr; @@ -3848,7 +3848,7 @@ HRESULT get_system_fontcollection(IDWriteFactory3 *factory, IDWriteFontCollectio return hr; } -static HRESULT eudc_collection_add_family(IDWriteFactory3 *factory, struct dwrite_fontcollection *collection, +static HRESULT eudc_collection_add_family(IDWriteFactory4 *factory, struct dwrite_fontcollection *collection, const WCHAR *keynameW, const WCHAR *pathW) { static const WCHAR defaultfontW[] = {'S','y','s','t','e','m','D','e','f','a','u','l','t','E','U','D','C','F','o','n','t',0}; @@ -3927,7 +3927,7 @@ static HRESULT eudc_collection_add_family(IDWriteFactory3 *factory, struct dwrit return hr; } -HRESULT get_eudc_fontcollection(IDWriteFactory3 *factory, IDWriteFontCollection **ret) +HRESULT get_eudc_fontcollection(IDWriteFactory4 *factory, IDWriteFontCollection **ret) { static const WCHAR eudckeyfmtW[] = {'E','U','D','C','\\','%','u',0}; struct dwrite_fontcollection *collection; @@ -5535,7 +5535,7 @@ static ULONG WINAPI fontfacereference_Release(IDWriteFontFaceReference *iface) if (!ref) { IDWriteFontFile_Release(This->file); - IDWriteFactory3_Release(This->factory); + IDWriteFactory4_Release(This->factory); heap_free(This); } @@ -5568,7 +5568,7 @@ static HRESULT WINAPI fontfacereference_CreateFontFaceWithSimulations(IDWriteFon if (FAILED(hr)) return hr; - hr = IDWriteFactory3_CreateFontFace(This->factory, face_type, 1, &This->file, This->index, simulations, &fontface); + hr = IDWriteFactory4_CreateFontFace(This->factory, face_type, 1, &This->file, This->index, simulations, &fontface); if (SUCCEEDED(hr)) { hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace3, (void**)ret); IDWriteFontFace_Release(fontface); @@ -5632,7 +5632,7 @@ static HRESULT WINAPI fontfacereference_GetFontFile(IDWriteFontFaceReference *if if (FAILED(hr)) return hr; - hr = IDWriteFactory3_CreateCustomFontFileReference(This->factory, key, key_size, loader, file); + hr = IDWriteFactory4_CreateCustomFontFileReference(This->factory, key, key_size, loader, file); IDWriteFontFileLoader_Release(loader); return hr; @@ -5733,7 +5733,7 @@ static const IDWriteFontFaceReferenceVtbl fontfacereferencevtbl = { fontfacereference_EnqueueFileFragmentDownloadRequest }; -HRESULT create_fontfacereference(IDWriteFactory3 *factory, IDWriteFontFile *file, UINT32 index, +HRESULT create_fontfacereference(IDWriteFactory4 *factory, IDWriteFontFile *file, UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFaceReference **ret) { struct dwrite_fontfacereference *ref; @@ -5751,7 +5751,7 @@ HRESULT create_fontfacereference(IDWriteFactory3 *factory, IDWriteFontFile *file ref->ref = 1; ref->factory = factory; - IDWriteFactory3_AddRef(ref->factory); + IDWriteFactory4_AddRef(ref->factory); ref->file = file; IDWriteFontFile_AddRef(ref->file); ref->index = index; diff --git a/dlls/dwrite/gdiinterop.c b/dlls/dwrite/gdiinterop.c index edcbd58..886bebb 100644 --- a/dlls/dwrite/gdiinterop.c +++ b/dlls/dwrite/gdiinterop.c @@ -599,14 +599,14 @@ static ULONG WINAPI gdiinterop_AddRef(IDWriteGdiInterop1 *iface) { struct gdiinterop *This = impl_from_IDWriteGdiInterop1(iface); TRACE("(%p)\n", This); - return IDWriteFactory3_AddRef(This->factory); + return IDWriteFactory4_AddRef(This->factory); } static ULONG WINAPI gdiinterop_Release(IDWriteGdiInterop1 *iface) { struct gdiinterop *This = impl_from_IDWriteGdiInterop1(iface); TRACE("(%p)\n", This); - return IDWriteFactory3_Release(This->factory); + return IDWriteFactory4_Release(This->factory); } static HRESULT WINAPI gdiinterop_CreateFontFromLOGFONT(IDWriteGdiInterop1 *iface, @@ -805,7 +805,7 @@ static HRESULT WINAPI gdiinterop_CreateFontFaceFromHdc(IDWriteGdiInterop1 *iface return E_FAIL; } - hr = IDWriteFactory3_CreateFontFileReference(This->factory, fileinfo->path, &fileinfo->writetime, + hr = IDWriteFactory4_CreateFontFileReference(This->factory, fileinfo->path, &fileinfo->writetime, &file); heap_free(fileinfo); if (FAILED(hr)) @@ -819,7 +819,7 @@ static HRESULT WINAPI gdiinterop_CreateFontFaceFromHdc(IDWriteGdiInterop1 *iface } /* Simulations flags values match DWRITE_FONT_SIMULATIONS */ - hr = IDWriteFactory3_CreateFontFace(This->factory, facetype, 1, &file, info.face_index, info.simulations, + hr = IDWriteFactory4_CreateFontFace(This->factory, facetype, 1, &file, info.face_index, info.simulations, fontface); IDWriteFontFile_Release(file); return hr; @@ -852,7 +852,7 @@ static HRESULT WINAPI gdiinterop1_CreateFontFromLOGFONT(IDWriteGdiInterop1 *ifac if (collection) IDWriteFontCollection_AddRef(collection); else { - hr = IDWriteFactory3_GetSystemFontCollection(This->factory, FALSE, (IDWriteFontCollection1**)&collection, FALSE); + hr = IDWriteFactory4_GetSystemFontCollection(This->factory, FALSE, (IDWriteFontCollection1**)&collection, FALSE); if (FAILED(hr)) { ERR("failed to get system font collection: 0x%08x.\n", hr); return hr; @@ -957,7 +957,7 @@ static const struct IDWriteGdiInterop1Vtbl gdiinteropvtbl = { gdiinterop1_GetMatchingFontsByLOGFONT }; -void gdiinterop_init(struct gdiinterop *interop, IDWriteFactory3 *factory) +void gdiinterop_init(struct gdiinterop *interop, IDWriteFactory4 *factory) { interop->IDWriteGdiInterop1_iface.lpVtbl = &gdiinteropvtbl; /* Interop is a part of a factory, sharing its refcount. diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index b95dffa..706ed4e 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -235,7 +235,7 @@ struct dwrite_textlayout { IDWriteTextAnalysisSource1 IDWriteTextAnalysisSource1_iface; LONG ref; - IDWriteFactory3 *factory; + IDWriteFactory4 *factory; WCHAR *str; UINT32 len; @@ -801,7 +801,7 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout) IDWriteFontFallback_AddRef(fallback); } else { - hr = IDWriteFactory3_GetSystemFontFallback(layout->factory, &fallback); + hr = IDWriteFactory4_GetSystemFontFallback(layout->factory, &fallback); if (FAILED(hr)) return hr; } @@ -825,7 +825,7 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout) IDWriteFontCollection_AddRef(collection); } else - IDWriteFactory3_GetSystemFontCollection(layout->factory, FALSE, (IDWriteFontCollection1**)&collection, FALSE); + IDWriteFactory4_GetSystemFontCollection(layout->factory, FALSE, (IDWriteFontCollection1**)&collection, FALSE); hr = create_matching_font(collection, range->fontfamily, range->weight, range->style, range->stretch, &font); @@ -2653,7 +2653,7 @@ static ULONG WINAPI dwritetextlayout_Release(IDWriteTextLayout3 *iface) TRACE("(%p)->(%d)\n", This, ref); if (!ref) { - IDWriteFactory3_Release(This->factory); + IDWriteFactory4_Release(This->factory); free_layout_ranges_list(This); free_layout_eruns(This); free_layout_runs(This); @@ -4617,7 +4617,7 @@ static HRESULT init_textlayout(const struct textlayout_desc *desc, struct dwrite layout->transform = desc->transform ? *desc->transform : identity; layout->factory = desc->factory; - IDWriteFactory3_AddRef(layout->factory); + IDWriteFactory4_AddRef(layout->factory); list_add_head(&layout->ranges, &range->entry); list_add_head(&layout->strike_ranges, &strike->entry); list_add_head(&layout->underline_ranges, &underline->entry); @@ -4778,7 +4778,7 @@ static inline BOOL is_flow_direction_vert(DWRITE_FLOW_DIRECTION direction) (direction == DWRITE_FLOW_DIRECTION_BOTTOM_TO_TOP); } -HRESULT create_trimmingsign(IDWriteFactory3 *factory, IDWriteTextFormat *format, IDWriteInlineObject **sign) +HRESULT create_trimmingsign(IDWriteFactory4 *factory, IDWriteTextFormat *format, IDWriteInlineObject **sign) { static const WCHAR ellipsisW = 0x2026; struct dwrite_trimmingsign *This; @@ -4804,7 +4804,7 @@ HRESULT create_trimmingsign(IDWriteFactory3 *factory, IDWriteTextFormat *format, This->IDWriteInlineObject_iface.lpVtbl = &dwritetrimmingsignvtbl; This->ref = 1; - hr = IDWriteFactory3_CreateTextLayout(factory, &ellipsisW, 1, format, 0.0f, 0.0f, &This->layout); + hr = IDWriteFactory4_CreateTextLayout(factory, &ellipsisW, 1, format, 0.0f, 0.0f, &This->layout); if (FAILED(hr)) { heap_free(This); return hr; diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 194c645..cf9117a 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -33,8 +33,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite); -static IDWriteFactory3 *shared_factory; -static void release_shared_factory(IDWriteFactory3*); +static IDWriteFactory4 *shared_factory; +static void release_shared_factory(IDWriteFactory4*); BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved) { @@ -519,7 +519,7 @@ struct fileloader }; struct dwritefactory { - IDWriteFactory3 IDWriteFactory3_iface; + IDWriteFactory4 IDWriteFactory4_iface; LONG ref; IDWriteFontCollection1 *system_collection; @@ -534,9 +534,9 @@ struct dwritefactory { struct list file_loaders; }; -static inline struct dwritefactory *impl_from_IDWriteFactory3(IDWriteFactory3 *iface) +static inline struct dwritefactory *impl_from_IDWriteFactory4(IDWriteFactory4 *iface) { - return CONTAINING_RECORD(iface, struct dwritefactory, IDWriteFactory3_iface); + return CONTAINING_RECORD(iface, struct dwritefactory, IDWriteFactory4_iface); } static void release_fontface_cache(struct list *fontfaces) @@ -584,11 +584,11 @@ static void release_dwritefactory(struct dwritefactory *factory) heap_free(factory); } -static void release_shared_factory(IDWriteFactory3 *iface) +static void release_shared_factory(IDWriteFactory4 *iface) { struct dwritefactory *factory; if (!iface) return; - factory = impl_from_IDWriteFactory3(iface); + factory = impl_from_IDWriteFactory4(iface); release_dwritefactory(factory); } @@ -620,20 +620,21 @@ static struct collectionloader *factory_get_collection_loader(struct dwritefacto return found; } -static HRESULT WINAPI dwritefactory_QueryInterface(IDWriteFactory3 *iface, REFIID riid, void **obj) +static HRESULT WINAPI dwritefactory_QueryInterface(IDWriteFactory4 *iface, REFIID riid, void **obj) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj); - if (IsEqualIID(riid, &IID_IDWriteFactory3) || + if (IsEqualIID(riid, &IID_IDWriteFactory4) || + IsEqualIID(riid, &IID_IDWriteFactory3) || IsEqualIID(riid, &IID_IDWriteFactory2) || IsEqualIID(riid, &IID_IDWriteFactory1) || IsEqualIID(riid, &IID_IDWriteFactory) || IsEqualIID(riid, &IID_IUnknown)) { *obj = iface; - IDWriteFactory3_AddRef(iface); + IDWriteFactory4_AddRef(iface); return S_OK; } @@ -642,17 +643,17 @@ static HRESULT WINAPI dwritefactory_QueryInterface(IDWriteFactory3 *iface, REFII return E_NOINTERFACE; } -static ULONG WINAPI dwritefactory_AddRef(IDWriteFactory3 *iface) +static ULONG WINAPI dwritefactory_AddRef(IDWriteFactory4 *iface) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); ULONG ref = InterlockedIncrement(&This->ref); TRACE("(%p)->(%d)\n", This, ref); return ref; } -static ULONG WINAPI dwritefactory_Release(IDWriteFactory3 *iface) +static ULONG WINAPI dwritefactory_Release(IDWriteFactory4 *iface) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p)->(%d)\n", This, ref); @@ -663,16 +664,16 @@ static ULONG WINAPI dwritefactory_Release(IDWriteFactory3 *iface) return ref; } -static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory3 *iface, +static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory4 *iface, IDWriteFontCollection **collection, BOOL check_for_updates) { - return IDWriteFactory3_GetSystemFontCollection(iface, FALSE, (IDWriteFontCollection1**)collection, check_for_updates); + return IDWriteFactory4_GetSystemFontCollection(iface, FALSE, (IDWriteFontCollection1**)collection, check_for_updates); } -static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory3 *iface, +static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory4 *iface, IDWriteFontCollectionLoader *loader, void const *key, UINT32 key_size, IDWriteFontCollection **collection) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); IDWriteFontFileEnumerator *enumerator; struct collectionloader *found; HRESULT hr; @@ -697,10 +698,10 @@ static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory3 * return hr; } -static HRESULT WINAPI dwritefactory_RegisterFontCollectionLoader(IDWriteFactory3 *iface, +static HRESULT WINAPI dwritefactory_RegisterFontCollectionLoader(IDWriteFactory4 *iface, IDWriteFontCollectionLoader *loader) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); struct collectionloader *entry; TRACE("(%p)->(%p)\n", This, loader); @@ -722,10 +723,10 @@ static HRESULT WINAPI dwritefactory_RegisterFontCollectionLoader(IDWriteFactory3 return S_OK; } -static HRESULT WINAPI dwritefactory_UnregisterFontCollectionLoader(IDWriteFactory3 *iface, +static HRESULT WINAPI dwritefactory_UnregisterFontCollectionLoader(IDWriteFactory4 *iface, IDWriteFontCollectionLoader *loader) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); struct collectionloader *found; TRACE("(%p)->(%p)\n", This, loader); @@ -744,10 +745,10 @@ static HRESULT WINAPI dwritefactory_UnregisterFontCollectionLoader(IDWriteFactor return S_OK; } -static HRESULT WINAPI dwritefactory_CreateFontFileReference(IDWriteFactory3 *iface, +static HRESULT WINAPI dwritefactory_CreateFontFileReference(IDWriteFactory4 *iface, WCHAR const *path, FILETIME const *writetime, IDWriteFontFile **font_file) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); UINT32 key_size; HRESULT hr; void *key; @@ -774,10 +775,10 @@ static HRESULT WINAPI dwritefactory_CreateFontFileReference(IDWriteFactory3 *ifa return hr; } -static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory3 *iface, +static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory4 *iface, void const *reference_key, UINT32 key_size, IDWriteFontFileLoader *loader, IDWriteFontFile **font_file) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); TRACE("(%p)->(%p %u %p %p)\n", This, reference_key, key_size, loader, font_file); @@ -791,10 +792,10 @@ static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory return create_font_file(loader, reference_key, key_size, font_file); } -HRESULT factory_get_cached_fontface(IDWriteFactory3 *iface, IDWriteFontFile * const *font_files, +HRESULT factory_get_cached_fontface(IDWriteFactory4 *iface, IDWriteFontFile * const *font_files, UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFace **font_face, struct list **cached_list) { - struct dwritefactory *factory = impl_from_IDWriteFactory3(iface); + struct dwritefactory *factory = impl_from_IDWriteFactory4(iface); struct fontfacecached *cached; IDWriteFontFileLoader *loader; struct list *fontfaces; @@ -873,11 +874,11 @@ void factory_cache_fontface(struct list *fontfaces, IDWriteFontFace3 *fontface) list_add_tail(fontfaces, &cached->entry); } -static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory3 *iface, +static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory4 *iface, DWRITE_FONT_FACE_TYPE req_facetype, UINT32 files_number, IDWriteFontFile* const* font_files, UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFace **font_face) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); DWRITE_FONT_FILE_TYPE file_type; DWRITE_FONT_FACE_TYPE face_type; struct fontface_desc desc; @@ -939,9 +940,9 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory3 *iface, return S_OK; } -static HRESULT WINAPI dwritefactory_CreateRenderingParams(IDWriteFactory3 *iface, IDWriteRenderingParams **params) +static HRESULT WINAPI dwritefactory_CreateRenderingParams(IDWriteFactory4 *iface, IDWriteRenderingParams **params) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); HMONITOR monitor; POINT pt; @@ -949,13 +950,13 @@ static HRESULT WINAPI dwritefactory_CreateRenderingParams(IDWriteFactory3 *iface pt.x = pt.y = 0; monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY); - return IDWriteFactory3_CreateMonitorRenderingParams(iface, monitor, params); + return IDWriteFactory4_CreateMonitorRenderingParams(iface, monitor, params); } -static HRESULT WINAPI dwritefactory_CreateMonitorRenderingParams(IDWriteFactory3 *iface, HMONITOR monitor, +static HRESULT WINAPI dwritefactory_CreateMonitorRenderingParams(IDWriteFactory4 *iface, HMONITOR monitor, IDWriteRenderingParams **params) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); IDWriteRenderingParams3 *params3; static int fixme_once = 0; HRESULT hr; @@ -965,30 +966,30 @@ static HRESULT WINAPI dwritefactory_CreateMonitorRenderingParams(IDWriteFactory3 if (!fixme_once++) FIXME("(%p): monitor setting ignored\n", monitor); - hr = IDWriteFactory3_CreateCustomRenderingParams(iface, 0.0f, 0.0f, 1.0f, 0.0f, DWRITE_PIXEL_GEOMETRY_FLAT, DWRITE_RENDERING_MODE_DEFAULT, + hr = IDWriteFactory4_CreateCustomRenderingParams(iface, 0.0f, 0.0f, 1.0f, 0.0f, DWRITE_PIXEL_GEOMETRY_FLAT, DWRITE_RENDERING_MODE_DEFAULT, DWRITE_GRID_FIT_MODE_DEFAULT, ¶ms3); *params = (IDWriteRenderingParams*)params3; return hr; } -static HRESULT WINAPI dwritefactory_CreateCustomRenderingParams(IDWriteFactory3 *iface, FLOAT gamma, FLOAT enhancedContrast, +static HRESULT WINAPI dwritefactory_CreateCustomRenderingParams(IDWriteFactory4 *iface, FLOAT gamma, FLOAT enhancedContrast, FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY geometry, DWRITE_RENDERING_MODE mode, IDWriteRenderingParams **params) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); IDWriteRenderingParams3 *params3; HRESULT hr; TRACE("(%p)->(%f %f %f %d %d %p)\n", This, gamma, enhancedContrast, cleartype_level, geometry, mode, params); - hr = IDWriteFactory3_CreateCustomRenderingParams(iface, gamma, enhancedContrast, 1.0f, cleartype_level, geometry, + hr = IDWriteFactory4_CreateCustomRenderingParams(iface, gamma, enhancedContrast, 1.0f, cleartype_level, geometry, mode, DWRITE_GRID_FIT_MODE_DEFAULT, ¶ms3); *params = (IDWriteRenderingParams*)params3; return hr; } -static HRESULT WINAPI dwritefactory_RegisterFontFileLoader(IDWriteFactory3 *iface, IDWriteFontFileLoader *loader) +static HRESULT WINAPI dwritefactory_RegisterFontFileLoader(IDWriteFactory4 *iface, IDWriteFontFileLoader *loader) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); struct fileloader *entry; TRACE("(%p)->(%p)\n", This, loader); @@ -1014,9 +1015,9 @@ static HRESULT WINAPI dwritefactory_RegisterFontFileLoader(IDWriteFactory3 *ifac return S_OK; } -static HRESULT WINAPI dwritefactory_UnregisterFontFileLoader(IDWriteFactory3 *iface, IDWriteFontFileLoader *loader) +static HRESULT WINAPI dwritefactory_UnregisterFontFileLoader(IDWriteFactory4 *iface, IDWriteFontFileLoader *loader) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); struct fileloader *found; TRACE("(%p)->(%p)\n", This, loader); @@ -1035,11 +1036,11 @@ static HRESULT WINAPI dwritefactory_UnregisterFontFileLoader(IDWriteFactory3 *if return S_OK; } -static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory3 *iface, WCHAR const* family_name, +static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory4 *iface, WCHAR const* family_name, IDWriteFontCollection *collection, DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, FLOAT size, WCHAR const *locale, IDWriteTextFormat **format) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); IDWriteFontCollection *syscollection = NULL; HRESULT hr; @@ -1047,7 +1048,7 @@ static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory3 *iface, WCH size, debugstr_w(locale), format); if (!collection) { - hr = IDWriteFactory3_GetSystemFontCollection(iface, FALSE, (IDWriteFontCollection1**)&syscollection, FALSE); + hr = IDWriteFactory4_GetSystemFontCollection(iface, FALSE, (IDWriteFontCollection1**)&syscollection, FALSE); if (FAILED(hr)) return hr; } @@ -1058,16 +1059,16 @@ static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory3 *iface, WCH return hr; } -static HRESULT WINAPI dwritefactory_CreateTypography(IDWriteFactory3 *iface, IDWriteTypography **typography) +static HRESULT WINAPI dwritefactory_CreateTypography(IDWriteFactory4 *iface, IDWriteTypography **typography) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); TRACE("(%p)->(%p)\n", This, typography); return create_typography(typography); } -static HRESULT WINAPI dwritefactory_GetGdiInterop(IDWriteFactory3 *iface, IDWriteGdiInterop **gdi_interop) +static HRESULT WINAPI dwritefactory_GetGdiInterop(IDWriteFactory4 *iface, IDWriteGdiInterop **gdi_interop) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); TRACE("(%p)->(%p)\n", This, gdi_interop); @@ -1076,10 +1077,10 @@ static HRESULT WINAPI dwritefactory_GetGdiInterop(IDWriteFactory3 *iface, IDWrit return S_OK; } -static HRESULT WINAPI dwritefactory_CreateTextLayout(IDWriteFactory3 *iface, WCHAR const* string, +static HRESULT WINAPI dwritefactory_CreateTextLayout(IDWriteFactory4 *iface, WCHAR const* string, UINT32 length, IDWriteTextFormat *format, FLOAT max_width, FLOAT max_height, IDWriteTextLayout **layout) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); struct textlayout_desc desc; TRACE("(%p)->(%s:%u %p %f %f %p)\n", This, debugstr_wn(string, length), length, format, max_width, max_height, layout); @@ -1097,11 +1098,11 @@ static HRESULT WINAPI dwritefactory_CreateTextLayout(IDWriteFactory3 *iface, WCH return create_textlayout(&desc, layout); } -static HRESULT WINAPI dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory3 *iface, WCHAR const* string, +static HRESULT WINAPI dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory4 *iface, WCHAR const* string, UINT32 length, IDWriteTextFormat *format, FLOAT max_width, FLOAT max_height, FLOAT pixels_per_dip, DWRITE_MATRIX const* transform, BOOL use_gdi_natural, IDWriteTextLayout **layout) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); struct textlayout_desc desc; TRACE("(%p)->(%s:%u %p %f %f %f %p %d %p)\n", This, debugstr_wn(string, length), length, format, max_width, max_height, @@ -1120,34 +1121,34 @@ static HRESULT WINAPI dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory return create_textlayout(&desc, layout); } -static HRESULT WINAPI dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory3 *iface, IDWriteTextFormat *format, +static HRESULT WINAPI dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory4 *iface, IDWriteTextFormat *format, IDWriteInlineObject **trimming_sign) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); TRACE("(%p)->(%p %p)\n", This, format, trimming_sign); return create_trimmingsign(iface, format, trimming_sign); } -static HRESULT WINAPI dwritefactory_CreateTextAnalyzer(IDWriteFactory3 *iface, IDWriteTextAnalyzer **analyzer) +static HRESULT WINAPI dwritefactory_CreateTextAnalyzer(IDWriteFactory4 *iface, IDWriteTextAnalyzer **analyzer) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); TRACE("(%p)->(%p)\n", This, analyzer); return get_textanalyzer(analyzer); } -static HRESULT WINAPI dwritefactory_CreateNumberSubstitution(IDWriteFactory3 *iface, DWRITE_NUMBER_SUBSTITUTION_METHOD method, +static HRESULT WINAPI dwritefactory_CreateNumberSubstitution(IDWriteFactory4 *iface, DWRITE_NUMBER_SUBSTITUTION_METHOD method, WCHAR const* locale, BOOL ignore_user_override, IDWriteNumberSubstitution **substitution) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); TRACE("(%p)->(%d %s %d %p)\n", This, method, debugstr_w(locale), ignore_user_override, substitution); return create_numbersubstitution(method, locale, ignore_user_override, substitution); } -static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory3 *iface, DWRITE_GLYPH_RUN const *run, +static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory4 *iface, DWRITE_GLYPH_RUN const *run, FLOAT ppdip, DWRITE_MATRIX const* transform, DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode, FLOAT originX, FLOAT originY, IDWriteGlyphRunAnalysis **analysis) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); struct glyphrunanalysis_desc desc; TRACE("(%p)->(%p %.2f %p %d %d %.2f %.2f %p)\n", This, run, ppdip, transform, rendering_mode, @@ -1170,10 +1171,10 @@ static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory3 *ifac return create_glyphrunanalysis(&desc, analysis); } -static HRESULT WINAPI dwritefactory1_GetEudcFontCollection(IDWriteFactory3 *iface, IDWriteFontCollection **collection, +static HRESULT WINAPI dwritefactory1_GetEudcFontCollection(IDWriteFactory4 *iface, IDWriteFontCollection **collection, BOOL check_for_updates) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); HRESULT hr = S_OK; TRACE("(%p)->(%p %d)\n", This, collection, check_for_updates); @@ -1192,25 +1193,25 @@ static HRESULT WINAPI dwritefactory1_GetEudcFontCollection(IDWriteFactory3 *ifac return hr; } -static HRESULT WINAPI dwritefactory1_CreateCustomRenderingParams(IDWriteFactory3 *iface, FLOAT gamma, +static HRESULT WINAPI dwritefactory1_CreateCustomRenderingParams(IDWriteFactory4 *iface, FLOAT gamma, FLOAT enhcontrast, FLOAT enhcontrast_grayscale, FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY geometry, DWRITE_RENDERING_MODE mode, IDWriteRenderingParams1** params) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); IDWriteRenderingParams3 *params3; HRESULT hr; TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %p)\n", This, gamma, enhcontrast, enhcontrast_grayscale, cleartype_level, geometry, mode, params); - hr = IDWriteFactory3_CreateCustomRenderingParams(iface, gamma, enhcontrast, enhcontrast_grayscale, + hr = IDWriteFactory4_CreateCustomRenderingParams(iface, gamma, enhcontrast, enhcontrast_grayscale, cleartype_level, geometry, mode, DWRITE_GRID_FIT_MODE_DEFAULT, ¶ms3); *params = (IDWriteRenderingParams1*)params3; return hr; } -static HRESULT WINAPI dwritefactory2_GetSystemFontFallback(IDWriteFactory3 *iface, IDWriteFontFallback **fallback) +static HRESULT WINAPI dwritefactory2_GetSystemFontFallback(IDWriteFactory4 *iface, IDWriteFontFallback **fallback) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); TRACE("(%p)->(%p)\n", This, fallback); @@ -1227,46 +1228,46 @@ static HRESULT WINAPI dwritefactory2_GetSystemFontFallback(IDWriteFactory3 *ifac return S_OK; } -static HRESULT WINAPI dwritefactory2_CreateFontFallbackBuilder(IDWriteFactory3 *iface, IDWriteFontFallbackBuilder **fallbackbuilder) +static HRESULT WINAPI dwritefactory2_CreateFontFallbackBuilder(IDWriteFactory4 *iface, IDWriteFontFallbackBuilder **fallbackbuilder) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); FIXME("(%p)->(%p): stub\n", This, fallbackbuilder); return E_NOTIMPL; } -static HRESULT WINAPI dwritefactory2_TranslateColorGlyphRun(IDWriteFactory3 *iface, FLOAT originX, FLOAT originY, +static HRESULT WINAPI dwritefactory2_TranslateColorGlyphRun(IDWriteFactory4 *iface, FLOAT originX, FLOAT originY, const DWRITE_GLYPH_RUN *run, const DWRITE_GLYPH_RUN_DESCRIPTION *rundescr, DWRITE_MEASURING_MODE mode, const DWRITE_MATRIX *transform, UINT32 palette, IDWriteColorGlyphRunEnumerator **colorlayers) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); TRACE("(%p)->(%.2f %.2f %p %p %d %p %u %p)\n", This, originX, originY, run, rundescr, mode, transform, palette, colorlayers); return create_colorglyphenum(originX, originY, run, rundescr, mode, transform, palette, colorlayers); } -static HRESULT WINAPI dwritefactory2_CreateCustomRenderingParams(IDWriteFactory3 *iface, FLOAT gamma, FLOAT contrast, +static HRESULT WINAPI dwritefactory2_CreateCustomRenderingParams(IDWriteFactory4 *iface, FLOAT gamma, FLOAT contrast, FLOAT grayscalecontrast, FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY geometry, DWRITE_RENDERING_MODE mode, DWRITE_GRID_FIT_MODE gridfit, IDWriteRenderingParams2 **params) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); IDWriteRenderingParams3 *params3; HRESULT hr; TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %d %p)\n", This, gamma, contrast, grayscalecontrast, cleartype_level, geometry, mode, gridfit, params); - hr = IDWriteFactory3_CreateCustomRenderingParams(iface, gamma, contrast, grayscalecontrast, + hr = IDWriteFactory4_CreateCustomRenderingParams(iface, gamma, contrast, grayscalecontrast, cleartype_level, geometry, mode, DWRITE_GRID_FIT_MODE_DEFAULT, ¶ms3); *params = (IDWriteRenderingParams2*)params3; return hr; } -static HRESULT WINAPI dwritefactory2_CreateGlyphRunAnalysis(IDWriteFactory3 *iface, const DWRITE_GLYPH_RUN *run, +static HRESULT WINAPI dwritefactory2_CreateGlyphRunAnalysis(IDWriteFactory4 *iface, const DWRITE_GLYPH_RUN *run, const DWRITE_MATRIX *transform, DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode, DWRITE_GRID_FIT_MODE gridfit_mode, DWRITE_TEXT_ANTIALIAS_MODE aa_mode, FLOAT originX, FLOAT originY, IDWriteGlyphRunAnalysis **analysis) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); struct glyphrunanalysis_desc desc; TRACE("(%p)->(%p %p %d %d %d %d %.2f %.2f %p)\n", This, run, transform, rendering_mode, measuring_mode, @@ -1284,12 +1285,12 @@ static HRESULT WINAPI dwritefactory2_CreateGlyphRunAnalysis(IDWriteFactory3 *ifa return create_glyphrunanalysis(&desc, analysis); } -static HRESULT WINAPI dwritefactory3_CreateGlyphRunAnalysis(IDWriteFactory3 *iface, DWRITE_GLYPH_RUN const *run, +static HRESULT WINAPI dwritefactory3_CreateGlyphRunAnalysis(IDWriteFactory4 *iface, DWRITE_GLYPH_RUN const *run, DWRITE_MATRIX const *transform, DWRITE_RENDERING_MODE1 rendering_mode, DWRITE_MEASURING_MODE measuring_mode, DWRITE_GRID_FIT_MODE gridfit_mode, DWRITE_TEXT_ANTIALIAS_MODE aa_mode, FLOAT originX, FLOAT originY, IDWriteGlyphRunAnalysis **analysis) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); FIXME("(%p)->(%p %p %d %d %d %d %.2f %.2f %p): stub\n", This, run, transform, rendering_mode, measuring_mode, gridfit_mode, aa_mode, originX, originY, analysis); @@ -1297,11 +1298,11 @@ static HRESULT WINAPI dwritefactory3_CreateGlyphRunAnalysis(IDWriteFactory3 *ifa return E_NOTIMPL; } -static HRESULT WINAPI dwritefactory3_CreateCustomRenderingParams(IDWriteFactory3 *iface, FLOAT gamma, FLOAT contrast, +static HRESULT WINAPI dwritefactory3_CreateCustomRenderingParams(IDWriteFactory4 *iface, FLOAT gamma, FLOAT contrast, FLOAT grayscale_contrast, FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY pixel_geometry, DWRITE_RENDERING_MODE1 rendering_mode, DWRITE_GRID_FIT_MODE gridfit_mode, IDWriteRenderingParams3 **params) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %d %p)\n", This, gamma, contrast, grayscale_contrast, cleartype_level, pixel_geometry, rendering_mode, gridfit_mode, params); @@ -1310,68 +1311,68 @@ static HRESULT WINAPI dwritefactory3_CreateCustomRenderingParams(IDWriteFactory3 gridfit_mode, params); } -static HRESULT WINAPI dwritefactory3_CreateFontFaceReference_(IDWriteFactory3 *iface, IDWriteFontFile *file, UINT32 index, +static HRESULT WINAPI dwritefactory3_CreateFontFaceReference_(IDWriteFactory4 *iface, IDWriteFontFile *file, UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFaceReference **reference) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); TRACE("(%p)->(%p %u %x %p)\n", This, file, index, simulations, reference); return create_fontfacereference(iface, file, index, simulations, reference); } -static HRESULT WINAPI dwritefactory3_CreateFontFaceReference(IDWriteFactory3 *iface, WCHAR const *path, FILETIME const *writetime, +static HRESULT WINAPI dwritefactory3_CreateFontFaceReference(IDWriteFactory4 *iface, WCHAR const *path, FILETIME const *writetime, UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFaceReference **reference) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); IDWriteFontFile *file; HRESULT hr; TRACE("(%p)->(%s %p %u %x, %p)\n", This, debugstr_w(path), writetime, index, simulations, reference); - hr = IDWriteFactory3_CreateFontFileReference(iface, path, writetime, &file); + hr = IDWriteFactory4_CreateFontFileReference(iface, path, writetime, &file); if (FAILED(hr)) { *reference = NULL; return hr; } - hr = IDWriteFactory3_CreateFontFaceReference_(iface, file, index, simulations, reference); + hr = IDWriteFactory4_CreateFontFaceReference_(iface, file, index, simulations, reference); IDWriteFontFile_Release(file); return hr; } -static HRESULT WINAPI dwritefactory3_GetSystemFontSet(IDWriteFactory3 *iface, IDWriteFontSet **fontset) +static HRESULT WINAPI dwritefactory3_GetSystemFontSet(IDWriteFactory4 *iface, IDWriteFontSet **fontset) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); FIXME("(%p)->(%p): stub\n", This, fontset); return E_NOTIMPL; } -static HRESULT WINAPI dwritefactory3_CreateFontSetBuilder(IDWriteFactory3 *iface, IDWriteFontSetBuilder **builder) +static HRESULT WINAPI dwritefactory3_CreateFontSetBuilder(IDWriteFactory4 *iface, IDWriteFontSetBuilder **builder) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); FIXME("(%p)->(%p): stub\n", This, builder); return E_NOTIMPL; } -static HRESULT WINAPI dwritefactory3_CreateFontCollectionFromFontSet(IDWriteFactory3 *iface, IDWriteFontSet *fontset, +static HRESULT WINAPI dwritefactory3_CreateFontCollectionFromFontSet(IDWriteFactory4 *iface, IDWriteFontSet *fontset, IDWriteFontCollection1 **collection) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); FIXME("(%p)->(%p %p): stub\n", This, fontset, collection); return E_NOTIMPL; } -static HRESULT WINAPI dwritefactory3_GetSystemFontCollection(IDWriteFactory3 *iface, BOOL include_downloadable, +static HRESULT WINAPI dwritefactory3_GetSystemFontCollection(IDWriteFactory4 *iface, BOOL include_downloadable, IDWriteFontCollection1 **collection, BOOL check_for_updates) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); HRESULT hr = S_OK; TRACE("(%p)->(%d %p %d)\n", This, include_downloadable, collection, check_for_updates); @@ -1393,16 +1394,49 @@ static HRESULT WINAPI dwritefactory3_GetSystemFontCollection(IDWriteFactory3 *if return hr; } -static HRESULT WINAPI dwritefactory3_GetFontDownloadQueue(IDWriteFactory3 *iface, IDWriteFontDownloadQueue **queue) +static HRESULT WINAPI dwritefactory3_GetFontDownloadQueue(IDWriteFactory4 *iface, IDWriteFontDownloadQueue **queue) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); FIXME("(%p)->(%p): stub\n", This, queue); return E_NOTIMPL; } -static const struct IDWriteFactory3Vtbl dwritefactoryvtbl = { +static HRESULT WINAPI dwritefactory4_TranslateColorGlyphRun(IDWriteFactory4 *iface, D2D1_POINT_2F baseline_origin, + DWRITE_GLYPH_RUN const *run, DWRITE_GLYPH_RUN_DESCRIPTION const *run_desc, DWRITE_GLYPH_IMAGE_FORMATS desired_formats, + DWRITE_MEASURING_MODE measuring_mode, DWRITE_MATRIX const *transform, UINT32 palette, IDWriteColorGlyphRunEnumerator1 **layers) +{ + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); + + FIXME("(%p)->(%p %p %u %d %p %u %p): stub\n", This, run, run_desc, desired_formats, measuring_mode, + transform, palette, layers); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefactory4_ComputeGlyphOrigins_(IDWriteFactory4 *iface, DWRITE_GLYPH_RUN const *run, + D2D1_POINT_2F baseline_origin, D2D1_POINT_2F *origins) +{ + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); + + FIXME("(%p)->(%p %p): stub\n", This, run, origins); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefactory4_ComputeGlyphOrigins(IDWriteFactory4 *iface, DWRITE_GLYPH_RUN const *run, + DWRITE_MEASURING_MODE measuring_mode, D2D1_POINT_2F baseline_origin, DWRITE_MATRIX const *transform, + D2D1_POINT_2F *origins) +{ + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); + + FIXME("(%p)->(%p %d %p %p): stub\n", This, run, measuring_mode, transform, origins); + + return E_NOTIMPL; +} + +static const struct IDWriteFactory4Vtbl dwritefactoryvtbl = { dwritefactory_QueryInterface, dwritefactory_AddRef, dwritefactory_Release, @@ -1442,24 +1476,27 @@ static const struct IDWriteFactory3Vtbl dwritefactoryvtbl = { dwritefactory3_CreateFontSetBuilder, dwritefactory3_CreateFontCollectionFromFontSet, dwritefactory3_GetSystemFontCollection, - dwritefactory3_GetFontDownloadQueue + dwritefactory3_GetFontDownloadQueue, + dwritefactory4_TranslateColorGlyphRun, + dwritefactory4_ComputeGlyphOrigins_, + dwritefactory4_ComputeGlyphOrigins }; -static ULONG WINAPI shareddwritefactory_AddRef(IDWriteFactory3 *iface) +static ULONG WINAPI shareddwritefactory_AddRef(IDWriteFactory4 *iface) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); TRACE("(%p)\n", This); return 2; } -static ULONG WINAPI shareddwritefactory_Release(IDWriteFactory3 *iface) +static ULONG WINAPI shareddwritefactory_Release(IDWriteFactory4 *iface) { - struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + struct dwritefactory *This = impl_from_IDWriteFactory4(iface); TRACE("(%p)\n", This); return 1; } -static const struct IDWriteFactory3Vtbl shareddwritefactoryvtbl = { +static const struct IDWriteFactory4Vtbl shareddwritefactoryvtbl = { dwritefactory_QueryInterface, shareddwritefactory_AddRef, shareddwritefactory_Release, @@ -1504,12 +1541,12 @@ static const struct IDWriteFactory3Vtbl shareddwritefactoryvtbl = { static void init_dwritefactory(struct dwritefactory *factory, DWRITE_FACTORY_TYPE type) { - factory->IDWriteFactory3_iface.lpVtbl = type == DWRITE_FACTORY_TYPE_SHARED ? &shareddwritefactoryvtbl : &dwritefactoryvtbl; + factory->IDWriteFactory4_iface.lpVtbl = type == DWRITE_FACTORY_TYPE_SHARED ? &shareddwritefactoryvtbl : &dwritefactoryvtbl; factory->ref = 1; factory->localfontfileloader = NULL; factory->system_collection = NULL; factory->eudc_collection = NULL; - gdiinterop_init(&factory->interop, &factory->IDWriteFactory3_iface); + gdiinterop_init(&factory->interop, &factory->IDWriteFactory4_iface); factory->fallback = NULL; list_init(&factory->collection_loaders); @@ -1527,7 +1564,7 @@ HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnkno *ret = NULL; if (type == DWRITE_FACTORY_TYPE_SHARED && shared_factory) - return IDWriteFactory3_QueryInterface(shared_factory, riid, (void**)ret); + return IDWriteFactory4_QueryInterface(shared_factory, riid, (void**)ret); factory = heap_alloc(sizeof(struct dwritefactory)); if (!factory) return E_OUTOFMEMORY; @@ -1535,12 +1572,12 @@ HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnkno init_dwritefactory(factory, type); if (type == DWRITE_FACTORY_TYPE_SHARED) - if (InterlockedCompareExchangePointer((void**)&shared_factory, &factory->IDWriteFactory3_iface, NULL)) { - release_shared_factory(&factory->IDWriteFactory3_iface); - return IDWriteFactory3_QueryInterface(shared_factory, riid, (void**)ret); + if (InterlockedCompareExchangePointer((void**)&shared_factory, &factory->IDWriteFactory4_iface, NULL)) { + release_shared_factory(&factory->IDWriteFactory4_iface); + return IDWriteFactory4_QueryInterface(shared_factory, riid, (void**)ret); } - hr = IDWriteFactory3_QueryInterface(&factory->IDWriteFactory3_iface, riid, (void**)ret); - IDWriteFactory3_Release(&factory->IDWriteFactory3_iface); + hr = IDWriteFactory4_QueryInterface(&factory->IDWriteFactory4_iface, riid, (void**)ret); + IDWriteFactory4_Release(&factory->IDWriteFactory4_iface); return hr; } -- 2.9.3 From piotr at codeweavers.com Tue Oct 11 08:51:23 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Tue, 11 Oct 2016 15:51:23 +0200 Subject: msvcp100: Add stdext::threads::_Mtx_* implementation Message-ID: <1b313234-d8ba-5121-fe1a-a284485302fc@codeweavers.com> Signed-off-by: Piotr Caban --- dlls/msvcp100/msvcp100.spec | 16 ++++++++-------- dlls/msvcp110/msvcp110.spec | 16 ++++++++-------- dlls/msvcp120/msvcp120.spec | 16 ++++++++-------- dlls/msvcp120/tests/msvcp120.c | 38 +++++++++++++++++++++++++++++++++++++ dlls/msvcp120_app/msvcp120_app.spec | 16 ++++++++-------- dlls/msvcp140/msvcp140.spec | 16 ++++++++-------- dlls/msvcp90/misc.c | 21 ++++++++++++++++++++ 7 files changed, 99 insertions(+), 40 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-msvcp100-Add-stdext-threads-_Mtx_-implementation.txt Type: text/x-patch Size: 13895 bytes Desc: not available URL: From jre.winesim at gmail.com Tue Oct 11 09:21:02 2016 From: jre.winesim at gmail.com (Jens Reyer) Date: Tue, 11 Oct 2016 16:21:02 +0200 Subject: [PATCH v4 0/2] Don't call exit in the shared library. Message-ID: <20161011142104.18677-1-jre.winesim@gmail.com> v1: use asserts for mmap failure modes https://www.winehq.org/pipermail/wine-devel/2014-December/106096.html v2: use abort instead of exit for shared library failure modes https://www.winehq.org/pipermail/wine-devel/2015-July/108555.html v3: rebase v2, split commits per file v4: Drop all changes that don't trigger the lintian warning. This includes dropping the wrong ones pointed out by Sebastian Lackner (Thanks a lot! Note however that it always compiled just fine with these changes) and the rejected ones for wpp (I assume they are not related to the shared library). For dropping the other changes I completely relied on the lintian tool, but can't really judge if dropping them is the right thing to do. I attach them to this mail (PATCH v4 0/2) to ease commenting on them (but not as patch submission for now). Any feedback would be helpful for progressing in Debian with this. In the end I'd like to have any issues related to this topic solved and completely drop that patch in Debian. Thanks in advance! jre diff --git a/libs/port/spawn.c b/libs/port/spawn.c index 97364e7..7bc1ba4 100644 --- a/libs/port/spawn.c +++ b/libs/port/spawn.c @@ -62,13 +62,13 @@ int _spawnvp(int mode, const char *cmdname, const char *const argv[]) signal( SIGPIPE, SIG_DFL ); execvp(cmdname, (char **)argv); - _exit(1); + abort(); } if (pid == -1) return -1; - if (mode == _P_OVERLAY) exit(0); + if (mode == _P_OVERLAY) abort(); if (mode == _P_WAIT || mode == _P_DETACH) { diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c index 0946407..8bdda00 100644 --- a/libs/wine/ldt.c +++ b/libs/wine/ldt.c @@ -192,7 +192,7 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry ) { perror("i386_set_ldt"); fprintf( stderr, "Did you reconfigure the kernel with \"options USER_LDT\"?\n" ); - exit(1); + abort(); } } #elif defined(__svr4__) || defined(_SCO_DS) @@ -213,7 +213,7 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry ) perror("i386_set_ldt"); #else fprintf( stderr, "No LDT support on this platform\n" ); - exit(1); + abort(); #endif if (ret >= 0) diff --git a/libs/wine/mmap.c b/libs/wine/mmap.c index 1a3ca59..83e6a86 100644 --- a/libs/wine/mmap.c +++ b/libs/wine/mmap.c @@ -76,7 +76,7 @@ static inline int get_fdzero(void) if ((fd = open( "/dev/zero", O_RDONLY )) == -1) { perror( "/dev/zero: open" ); - exit(1); + abort(); } } return fd; @@ -128,7 +128,7 @@ static int try_mmap_fixed (void *addr, size_t len, int prot, int flags, if ( (pid = vfork()) == -1 ) { perror("try_mmap_fixed: vfork"); - exit(1); + abort(); } if ( pid == 0 ) { -- 2.9.3 From jre.winesim at gmail.com Tue Oct 11 09:21:04 2016 From: jre.winesim at gmail.com (Jens Reyer) Date: Tue, 11 Oct 2016 16:21:04 +0200 Subject: [PATCH v4 2/2] libwine: Don't call exit in the shared library. In-Reply-To: <20161011142104.18677-1-jre.winesim@gmail.com> References: <20161011142104.18677-1-jre.winesim@gmail.com> Message-ID: <20161011142104.18677-3-jre.winesim@gmail.com> From: Michael Gilbert Signed-off-by: Jens Reyer --- libs/wine/debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/wine/debug.c b/libs/wine/debug.c index 8b04ef9..6ed70b7 100644 --- a/libs/wine/debug.c +++ b/libs/wine/debug.c @@ -186,7 +186,7 @@ static void debug_usage(void) " turns on all messages except warning heap messages\n" "Available message classes: err, warn, fixme, trace\n"; write( 2, usage, sizeof(usage) - 1 ); - exit(1); + abort(); } -- 2.9.3 From jre.winesim at gmail.com Tue Oct 11 09:21:03 2016 From: jre.winesim at gmail.com (Jens Reyer) Date: Tue, 11 Oct 2016 16:21:03 +0200 Subject: [PATCH v4 1/2] libwine: Don't call exit in the shared library. In-Reply-To: <20161011142104.18677-1-jre.winesim@gmail.com> References: <20161011142104.18677-1-jre.winesim@gmail.com> Message-ID: <20161011142104.18677-2-jre.winesim@gmail.com> From: Michael Gilbert Signed-off-by: Jens Reyer --- libs/wine/config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/wine/config.c b/libs/wine/config.c index 3b5dd68..c0b3bdd 100644 --- a/libs/wine/config.c +++ b/libs/wine/config.c @@ -68,7 +68,7 @@ static void fatal_error( const char *err, ... ) fprintf( stderr, "wine: " ); vfprintf( stderr, err, args ); va_end( args ); - exit(1); + abort(); } /* die on a fatal error */ @@ -81,7 +81,7 @@ static void fatal_perror( const char *err, ... ) vfprintf( stderr, err, args ); perror( " " ); va_end( args ); - exit(1); + abort(); } /* malloc wrapper */ -- 2.9.3 From madewokherd at gmail.com Tue Oct 11 11:06:56 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Tue, 11 Oct 2016 11:06:56 -0500 Subject: gdiplus: Implement EMR_EXTSELECTCLIPRGN playback. Message-ID: <1476202016-17839-1-git-send-email-madewokherd@gmail.com> From: Vincent Povirk Signed-off-by: Vincent Povirk --- dlls/gdiplus/metafile.c | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index 32cd04e..69d8a16 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -1040,21 +1040,27 @@ GpStatus WINGDIPAPI GdipGetHemfFromMetafile(GpMetafile *metafile, HENHMETAFILE * return Ok; } -static GpStatus METAFILE_PlaybackUpdateGdiTransform(GpMetafile *metafile) +static void METAFILE_GetFinalGdiTransform(const GpMetafile *metafile, XFORM *result) { - XFORM combined, final; const GpRectF *rect; const GpPointF *pt; /* This transforms metafile device space to output points. */ rect = &metafile->src_rect; pt = metafile->playback_points; - final.eM11 = (pt[1].X - pt[0].X) / rect->Width; - final.eM21 = (pt[2].X - pt[0].X) / rect->Height; - final.eDx = pt[0].X - final.eM11 * rect->X - final.eM21 * rect->Y; - final.eM12 = (pt[1].Y - pt[0].Y) / rect->Width; - final.eM22 = (pt[2].Y - pt[0].Y) / rect->Height; - final.eDy = pt[0].Y - final.eM12 * rect->X - final.eM22 * rect->Y; + result->eM11 = (pt[1].X - pt[0].X) / rect->Width; + result->eM21 = (pt[2].X - pt[0].X) / rect->Height; + result->eDx = pt[0].X - result->eM11 * rect->X - result->eM21 * rect->Y; + result->eM12 = (pt[1].Y - pt[0].Y) / rect->Width; + result->eM22 = (pt[2].Y - pt[0].Y) / rect->Height; + result->eDy = pt[0].Y - result->eM12 * rect->X - result->eM22 * rect->Y; +} + +static GpStatus METAFILE_PlaybackUpdateGdiTransform(GpMetafile *metafile) +{ + XFORM combined, final; + + METAFILE_GetFinalGdiTransform(metafile, &final); CombineTransform(&combined, &metafile->gdiworldtransform, &final); @@ -1154,7 +1160,6 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, case EMR_SETWINDOWEXTEX: case EMR_SETVIEWPORTORGEX: case EMR_SETVIEWPORTEXTEX: - case EMR_EXTSELECTCLIPRGN: case EMR_SCALEVIEWPORTEXTEX: case EMR_SCALEWINDOWEXTEX: case EMR_MODIFYWORLDTRANSFORM: @@ -1167,6 +1172,28 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, METAFILE_PlaybackUpdateGdiTransform(real_metafile); break; } + case EMR_EXTSELECTCLIPRGN: + { + DWORD rgndatasize = *(DWORD*)data; + DWORD mode = *(DWORD*)(data + 4); + const RGNDATA *rgndata = (const RGNDATA*)(data + 8); + HRGN hrgn = NULL; + + if (dataSize > 8) + { + XFORM final; + + METAFILE_GetFinalGdiTransform(metafile, &final); + + hrgn = ExtCreateRegion(&final, rgndatasize, rgndata); + } + + ExtSelectClipRgn(metafile->playback_dc, hrgn, mode); + + DeleteObject(hrgn); + + return Ok; + } default: break; } -- 2.7.4 From sebastian at fds-team.de Tue Oct 11 11:11:19 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Tue, 11 Oct 2016 18:11:19 +0200 Subject: user32/tests: Fix test failures on 64-bit testbot VMs. Message-ID: Signed-off-by: Sebastian Lackner --- Thanks Alexandre for pointing those out. Win64 testbots unfortunately throw a STATUS_HEAP_CORRUPTION exception when running this test (which is not really surprising, because the pointer is supposed to be freed). GlobalLock does not trigger the crash, but also does not provide correct results. Catching the exception might be possible, but is much more complicated. ;) For now, just disable the corresponding test on _WIN64. dlls/user32/tests/clipboard.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dlls/user32/tests/clipboard.c b/dlls/user32/tests/clipboard.c index 69bdba8..17fc028 100644 --- a/dlls/user32/tests/clipboard.c +++ b/dlls/user32/tests/clipboard.c @@ -1737,7 +1737,10 @@ static void test_handles( HWND hwnd ) h = SetClipboardData( 0xdeadbeef, hfixed ); ok( h == hfixed, "got %p\n", h ); ok( is_fixed( h ), "expected fixed mem %p\n", h ); +#ifndef _WIN64 + /* testing if hfixed2 is freed triggers an exception on Win64 */ ok( is_freed( hfixed2 ) || broken( !is_freed( hfixed2 )) /* < Vista */, "expected freed mem %p\n", hfixed2 ); +#endif r = CloseClipboard(); ok( r, "gle %d\n", GetLastError() ); -- 2.9.0 From nsivov at codeweavers.com Tue Oct 11 15:40:52 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Tue, 11 Oct 2016 23:40:52 +0300 Subject: [PATCH] d2d1: Implement GetDesktopDpi() Message-ID: <20161011204052.25775-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/d2d1/factory.c | 36 +++++++++++++++++++++++++++++++----- dlls/d2d1/tests/d2d1.c | 17 +++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 86c1690..b83d221 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -30,6 +30,9 @@ struct d2d_factory LONG refcount; ID3D10Device1 *device; + + float dpi_x; + float dpi_y; }; static inline struct d2d_factory *impl_from_ID2D1Factory(ID2D1Factory *iface) @@ -37,6 +40,24 @@ static inline struct d2d_factory *impl_from_ID2D1Factory(ID2D1Factory *iface) return CONTAINING_RECORD(iface, struct d2d_factory, ID2D1Factory_iface); } +static HRESULT d2d_factory_reload_sysmetrics(struct d2d_factory *factory) +{ + HDC hdc; + + if (!(hdc = GetDC(NULL))) + { + factory->dpi_x = factory->dpi_y = 96.0f; + return E_FAIL; + } + + factory->dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); + factory->dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); + + ReleaseDC(NULL, hdc); + + return S_OK; +} + static HRESULT STDMETHODCALLTYPE d2d_factory_QueryInterface(ID2D1Factory *iface, REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); @@ -84,17 +105,21 @@ static ULONG STDMETHODCALLTYPE d2d_factory_Release(ID2D1Factory *iface) static HRESULT STDMETHODCALLTYPE d2d_factory_ReloadSystemMetrics(ID2D1Factory *iface) { - FIXME("iface %p stub!\n", iface); + struct d2d_factory *factory = impl_from_ID2D1Factory(iface); - return E_NOTIMPL; + TRACE("iface %p.\n", iface); + + return d2d_factory_reload_sysmetrics(factory); } static void STDMETHODCALLTYPE d2d_factory_GetDesktopDpi(ID2D1Factory *iface, float *dpi_x, float *dpi_y) { - FIXME("iface %p, dpi_x %p, dpi_y %p stub!\n", iface, dpi_x, dpi_y); + struct d2d_factory *factory = impl_from_ID2D1Factory(iface); + + TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y); - *dpi_x = 96.0f; - *dpi_y = 96.0f; + *dpi_x = factory->dpi_x; + *dpi_y = factory->dpi_y; } static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRectangleGeometry(ID2D1Factory *iface, @@ -381,6 +406,7 @@ static void d2d_factory_init(struct d2d_factory *factory, D2D1_FACTORY_TYPE fact factory->ID2D1Factory_iface.lpVtbl = &d2d_factory_vtbl; factory->refcount = 1; + d2d_factory_reload_sysmetrics(factory); } HRESULT WINAPI D2D1CreateFactory(D2D1_FACTORY_TYPE factory_type, REFIID iid, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 38012ca..433b1a5 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -3099,6 +3099,22 @@ todo_wine ID2D1Factory_Release(factory); } +static void test_desktop_dpi(void) +{ + ID2D1Factory *factory; + float dpi_x, dpi_y; + HRESULT hr; + + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); + ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr); + + dpi_x = dpi_y = 0.0f; + ID2D1Factory_GetDesktopDpi(factory, &dpi_x, &dpi_y); + ok(dpi_x > 0.0f && dpi_y > 0.0f, "Got wrong dpi %f x %f.\n", dpi_x, dpi_y); + + ID2D1Factory_Release(factory); +} + START_TEST(d2d1) { test_clip(); @@ -3116,4 +3132,5 @@ START_TEST(d2d1) test_dc_target(); test_hwnd_target(); test_bitmap_target(); + test_desktop_dpi(); } -- 2.9.3 From austinenglish at gmail.com Tue Oct 11 18:21:20 2016 From: austinenglish at gmail.com (Austin English) Date: Tue, 11 Oct 2016 18:21:20 -0500 Subject: libs/wine: give user an error message if WINEARCH is not win32/win64 (try 2) Message-ID: Fixes https://bugs.winehq.org/show_bug.cgi?id=41378 See also https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=838474 -- -Austin GPG: 14FB D7EA A041 937B -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-libs-wine-give-user-an-error-message-if-WINEARCH-is-.patch Type: text/x-patch Size: 1133 bytes Desc: not available URL: From haleykd at users.sf.net Tue Oct 11 23:54:44 2016 From: haleykd at users.sf.net (Kenneth Haley) Date: Tue, 11 Oct 2016 22:54:44 -0600 Subject: [resend] riched20-add-support-for-EM_PASTESPECIAL Message-ID: -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-riched20-add-support-for-EM_PASTESPECIAL.patch Type: text/x-patch Size: 2692 bytes Desc: not available URL: From donat at enikeev.net Wed Oct 12 04:32:11 2016 From: donat at enikeev.net (Donat Enikeev) Date: Wed, 12 Oct 2016 12:32:11 +0300 Subject: [PATCH 1/2] Tests for CertRegisterSystemStore Message-ID: <1476264732-10965-1-git-send-email-donat@enikeev.net> Per bug https://bugs.winehq.org/show_bug.cgi?id=40314 --- dlls/crypt32/tests/store.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c index 4483936..2060889 100644 --- a/dlls/crypt32/tests/store.c +++ b/dlls/crypt32/tests/store.c @@ -123,6 +123,8 @@ static BOOL (WINAPI *pCertGetStoreProperty)(HCERTSTORE,DWORD,void*,DWORD*); static void (WINAPI *pCertRemoveStoreFromCollection)(HCERTSTORE,HCERTSTORE); static BOOL (WINAPI *pCertSetStoreProperty)(HCERTSTORE,DWORD,DWORD,const void*); static BOOL (WINAPI *pCertAddCertificateLinkToStore)(HCERTSTORE,PCCERT_CONTEXT,DWORD,PCCERT_CONTEXT*); +static BOOL (WINAPI *pCertRegisterSystemStore)(const void*,DWORD,void*,void*); +static BOOL (WINAPI *pCertUnregisterSystemStore)(const void*,DWORD); #define test_store_is_empty(store) _test_store_is_empty(__LINE__,store) static void _test_store_is_empty(unsigned line, HCERTSTORE store) @@ -1868,6 +1870,72 @@ static void testCertOpenSystemStore(void) RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW); } +static const struct +{ + DWORD cert_store; + LONG expected; + BOOL todo; +} reg_system_store_test_data[] = { + { CERT_SYSTEM_STORE_CURRENT_USER, TRUE, 0}, + /* Following tests could require administrator privileges and thus could be skipped */ + { CERT_SYSTEM_STORE_CURRENT_SERVICE, TRUE, 1}, + { CERT_SYSTEM_STORE_LOCAL_MACHINE, TRUE, 0}, + { CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, TRUE, 1}, + { CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, TRUE, 1}, + { CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, TRUE, 1} +}; + +static void testCertRegisterSystemStore(void) +{ + BOOL ret; + DWORD err = 0; + HCERTSTORE hstore; + static const WCHAR WineTestW[] = {'W','i','n','e','T','e','s','t',0}; + unsigned int i; + + if (!pCertRegisterSystemStore || !pCertUnregisterSystemStore) + { + win_skip("CertRegisterSystemStore() or CertUnregisterSystemStore() is not available\n"); + return; + } + + for (i = 0; i < sizeof(reg_system_store_test_data) / sizeof(reg_system_store_test_data[0]); i++) { + ret = pCertRegisterSystemStore(WineTestW, reg_system_store_test_data[i].cert_store, NULL, NULL); + if (!ret) { + err = GetLastError(); + if (err == ERROR_ACCESS_DENIED) { + win_skip("Insufficient privileges for the flag %08x test\n", reg_system_store_test_data[i].cert_store); + continue; + } + } + todo_wine_if (reg_system_store_test_data[i].todo) + ok( ret == reg_system_store_test_data[i].expected, "Registering failed with dwFlags=%08x: got %08x last error %d\n", + reg_system_store_test_data[i].cert_store, ret, err); + + hstore = CertOpenSystemStoreW(0, WineTestW); + if (hstore == NULL) + err = GetLastError(); + ok ( hstore != NULL, "Opening just registered store failed with dwFlags=%08x, last error %d\n", + reg_system_store_test_data[i].cert_store, err); + if (hstore != NULL) + CertCloseStore(hstore, CERT_CLOSE_STORE_FORCE_FLAG); + + ret = pCertUnregisterSystemStore(WineTestW, reg_system_store_test_data[i].cert_store); + if (!ret) + err = GetLastError(); + todo_wine_if (reg_system_store_test_data[i].todo) + ok( ret == reg_system_store_test_data[i].expected, "Unregistering failed with dwFlags=%08x: got %08x, last error %d\n", + reg_system_store_test_data[i].cert_store, ret, err); + + ret = pCertUnregisterSystemStore(WineTestW, reg_system_store_test_data[i].cert_store); + if (!ret) + err = GetLastError(); + ok( !ret, "Unregistering of non-existent store failed with dwFlags=%08x: got %08x, last error %d\n", + reg_system_store_test_data[i].cert_store, ret, err); + } + +} + struct EnumSystemStoreInfo { BOOL goOn; @@ -2808,6 +2876,8 @@ START_TEST(store) pCertRemoveStoreFromCollection = (void*)GetProcAddress(hdll, "CertRemoveStoreFromCollection"); pCertSetStoreProperty = (void*)GetProcAddress(hdll, "CertSetStoreProperty"); pCertAddCertificateLinkToStore = (void*)GetProcAddress(hdll, "CertAddCertificateLinkToStore"); + pCertRegisterSystemStore = (void*)GetProcAddress(hdll, "CertRegisterSystemStore"); + pCertUnregisterSystemStore = (void*)GetProcAddress(hdll, "CertUnregisterSystemStore"); /* various combinations of CertOpenStore */ testMemStore(); @@ -2821,6 +2891,7 @@ START_TEST(store) testSerializedStore(); testCloseStore(); + testCertRegisterSystemStore(); testCertOpenSystemStore(); testCertEnumSystemStore(); testStoreProperty(); -- 2.7.4 From donat at enikeev.net Wed Oct 12 04:32:12 2016 From: donat at enikeev.net (Donat Enikeev) Date: Wed, 12 Oct 2016 12:32:12 +0300 Subject: [PATCH 2/2] Cert(Un)RegisterSystemStore semi-stub In-Reply-To: <1476264732-10965-1-git-send-email-donat@enikeev.net> References: <1476264732-10965-1-git-send-email-donat@enikeev.net> Message-ID: <1476264732-10965-2-git-send-email-donat@enikeev.net> Per bug https://bugs.winehq.org/show_bug.cgi?id=40314 --- dlls/crypt32/crypt32.spec | 2 ++ dlls/crypt32/store.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec index 0d2a477..b5ce48c 100644 --- a/dlls/crypt32/crypt32.spec +++ b/dlls/crypt32/crypt32.spec @@ -78,6 +78,7 @@ @ stdcall CertRDNValueToStrA(long ptr ptr long) @ stdcall CertRDNValueToStrW(long ptr ptr long) @ stdcall CertRegisterPhysicalStore(ptr long wstr ptr ptr) +@ stdcall CertRegisterSystemStore(ptr long ptr ptr) @ stdcall CertRemoveEnhancedKeyUsageIdentifier(ptr str) @ stdcall CertRemoveStoreFromCollection(ptr ptr) @ stdcall CertSaveStore(ptr long long long ptr long) @@ -190,6 +191,7 @@ @ stdcall CryptUnprotectMemory(ptr long long) @ stdcall CryptUnregisterDefaultOIDFunction(long str wstr) @ stdcall CryptUnregisterOIDFunction(long str str) +@ stdcall CertUnregisterSystemStore(ptr long) @ stub CryptUnregisterOIDInfo @ stdcall CryptVerifyCertificateSignature(long long ptr long ptr) @ stdcall CryptVerifyCertificateSignatureEx(long long long ptr long ptr long ptr) diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c index d5d7443..735d59c 100644 --- a/dlls/crypt32/store.c +++ b/dlls/crypt32/store.c @@ -1390,6 +1390,71 @@ BOOL WINAPI CertRegisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags, return FALSE; } +BOOL WINAPI CertRegisterSystemStore(const void *pvSystemStore, DWORD dwFlags, + PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved) +{ + LONG rc; + BOOL ret = FALSE; + HKEY parent_key, store_key; + + if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG ) + { + FIXME("(%p, %08x, %p, %p): flag not supported\n", pvSystemStore, dwFlags, pStoreInfo, pvReserved); + return FALSE; + } + + TRACE("(%s, %08x, %p, %p)\n", debugstr_w(pvSystemStore), dwFlags, pStoreInfo, pvReserved); + + rc = CRYPT_OpenParentStore(dwFlags, NULL, &parent_key); + if (!rc) + { + rc = RegOpenKeyExW(parent_key, pvSystemStore, 0, KEY_READ, &store_key); + if (rc) + { + rc = RegCreateKeyExW(parent_key, pvSystemStore, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &store_key, NULL); + if (!rc) + ret = TRUE; + } else + ret = TRUE; + RegCloseKey(store_key); + } + + RegCloseKey(parent_key); + + return ret; +} + +BOOL WINAPI CertUnregisterSystemStore(const void *pvSystemStore, DWORD dwFlags) +{ + LONG rc; + BOOL ret = FALSE; + HKEY parent_key, store_key; + + if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG) + { + FIXME("(%p, %08x): flag not supported\n", pvSystemStore, dwFlags); + return FALSE; + } + + TRACE("(%s, %08x)\n", debugstr_w(pvSystemStore), dwFlags); + + rc = CRYPT_OpenParentStore(dwFlags, NULL, &parent_key); + if (!rc) + { + rc = RegOpenKeyExW(parent_key, pvSystemStore, 0, KEY_READ, &store_key); + if (!rc) + { + rc = RegDeleteTreeW(parent_key, pvSystemStore); + if (!rc) + ret = TRUE; + } + RegCloseKey(store_key); + } + + RegCloseKey(parent_key); + return ret; +} + static void EmptyStore_addref(WINECRYPT_CERTSTORE *store) { TRACE("(%p)\n", store); -- 2.7.4 From hans at codeweavers.com Wed Oct 12 04:53:41 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Wed, 12 Oct 2016 11:53:41 +0200 Subject: include: Avoid redefinition of EVENT_FILTER_DESCRIPTOR. Message-ID: <1476266021-14048-1-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- include/evntrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/evntrace.h b/include/evntrace.h index 6ebcfba..b54cd11 100644 --- a/include/evntrace.h +++ b/include/evntrace.h @@ -248,7 +248,7 @@ typedef struct _EVENT_TRACE_PROPERTIES ULONG LoggerNameOffset; } EVENT_TRACE_PROPERTIES, *PEVENT_TRACE_PROPERTIES; -typedef struct _EVENT_FILTER_DESCRIPTOR EVENT_FILTER_DESCRIPTOR, *PEVENT_FILTER_DESCRIPTOR; +typedef struct _EVENT_FILTER_DESCRIPTOR *PEVENT_FILTER_DESCRIPTOR; typedef struct _ENABLE_TRACE_PARAMETERS { -- 2.1.4 From aric at codeweavers.com Wed Oct 12 05:12:37 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 12 Oct 2016 12:12:37 +0200 Subject: [PATCH] winebus.sys: Implement IOCTL_HID_GET_STRING for hidraw Message-ID: <7c71567f-ff0e-721c-3834-acd2e74dd4de@codeweavers.com> Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_udev.c | 70 +++++++++++++++++++++++++++++++++++++++++++++ dlls/winebus.sys/main.c | 11 +++++++ 3 files changed, 82 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-winebus.sys-Implement-IOCTL_HID_GET_STRING-for-hidraw.txt Type: text/x-patch Size: 4340 bytes Desc: not available URL: From aricstewart at gmail.com Wed Oct 12 05:31:12 2016 From: aricstewart at gmail.com (Aric Stewart) Date: Wed, 12 Oct 2016 12:31:12 +0200 Subject: [PATCH 1/4] winehid.sys: Add HID minidriver Message-ID: <1291a2ff-314e-6857-23a2-9e2479058bf0@codeweavers.com> Signed-off-by: Aric Stewart --- MAINTAINERS | 1 + configure | 2 ++ configure.ac | 1 + dlls/winehid.sys/Makefile.in | 6 ++++++ dlls/winehid.sys/main.c | 38 ++++++++++++++++++++++++++++++++++++++ dlls/winehid.sys/winehid.sys.spec | 1 + loader/wine.inf.in | 14 ++++++++++++++ 7 files changed, 63 insertions(+) create mode 100644 dlls/winehid.sys/Makefile.in create mode 100644 dlls/winehid.sys/main.c create mode 100644 dlls/winehid.sys/winehid.sys.spec -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-winehid.sys-Add-HID-minidriver.txt Type: text/x-patch Size: 5274 bytes Desc: not available URL: From aric at codeweavers.com Wed Oct 12 05:31:22 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 12 Oct 2016 12:31:22 +0200 Subject: [PATCH 2/4] winehid.sys: Register as a HID minidriver Message-ID: <3dd99630-4a76-aa1c-5ab2-9b93f4d9d00e@codeweavers.com> Signed-off-by: Aric Stewart --- dlls/winehid.sys/Makefile.in | 2 +- dlls/winehid.sys/main.c | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-winehid.sys-Register-as-a-HID-minidriver.txt Type: text/x-patch Size: 1387 bytes Desc: not available URL: From aric at codeweavers.com Wed Oct 12 05:31:34 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 12 Oct 2016 12:31:34 +0200 Subject: [PATCH 3/4] include: Define IoSkipCurrentIrpStackLocation Message-ID: <0f78b650-ee07-0f00-8e7d-e8c54fa42a6f@codeweavers.com> Signed-off-by: Aric Stewart --- include/ddk/wdm.h | 2 ++ 1 file changed, 2 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0003-include-Define-IoSkipCurrentIrpStackLocation.txt Type: text/x-patch Size: 908 bytes Desc: not available URL: From aric at codeweavers.com Wed Oct 12 05:31:43 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 12 Oct 2016 12:31:43 +0200 Subject: [PATCH 4/4] winehid: Implement handing internal ioctls Message-ID: Mostly by passing them to the bus driver where platform specific actions happen Signed-off-by: Aric Stewart --- dlls/winehid.sys/main.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0004-winehid-Implement-handing-internal-ioctls.txt Type: text/x-patch Size: 2626 bytes Desc: not available URL: From huw at codeweavers.com Wed Oct 12 06:58:49 2016 From: huw at codeweavers.com (Huw Davies) Date: Wed, 12 Oct 2016 12:58:49 +0100 Subject: [PATCH 1/5] riched20: Add any paragraph numbering fonts to the font table. Message-ID: <1476273533-10193-1-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/writer.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index fe8c797..c3359c1 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -274,6 +274,10 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, if (item->member.run.para != prev_para) { + /* check for any para numbering text */ + if (item->member.run.para->fmt.wNumbering) + add_font_to_fonttbl( pStream, item->member.run.para->para_num.style ); + if ((pCell = item->member.para.pCell)) { ME_Border* borders[4] = { &pCell->member.cell.border.top, -- 2.8.2 From huw at codeweavers.com Wed Oct 12 06:58:50 2016 From: huw at codeweavers.com (Huw Davies) Date: Wed, 12 Oct 2016 12:58:50 +0100 Subject: [PATCH 2/5] riched20: Add a helper to find a font in the font table. Message-ID: <1476273533-10193-2-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/writer.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index c3359c1..838168e 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -237,6 +237,31 @@ static void add_font_to_fonttbl( ME_OutStream *stream, ME_Style *style ) } } +static BOOL find_font_in_fonttbl( ME_OutStream *stream, CHARFORMAT2W *fmt, unsigned int *idx ) +{ + WCHAR *facename; + int i; + + *idx = 0; + if (fmt->dwMask & CFM_FACE) + facename = fmt->szFaceName; + else + facename = stream->fonttbl[0].szFaceName; + for (i = 0; i < stream->nFontTblLen; i++) + { + if (facename == stream->fonttbl[i].szFaceName + || !lstrcmpW(facename, stream->fonttbl[i].szFaceName)) + if (!(fmt->dwMask & CFM_CHARSET) + || fmt->bCharSet == stream->fonttbl[i].bCharSet) + { + *idx = i; + break; + } + } + + return i < stream->nFontTblLen; +} + static void add_color_to_colortbl( ME_OutStream *stream, COLORREF color ) { int i; @@ -713,21 +738,9 @@ ME_StreamOutRTFCharProps(ME_OutStream *pStream, CHARFORMAT2W *fmt) } /* FIXME: How to emit CFM_WEIGHT? */ - if (fmt->dwMask & CFM_FACE || fmt->dwMask & CFM_CHARSET) { - WCHAR *szFaceName; - - if (fmt->dwMask & CFM_FACE) - szFaceName = fmt->szFaceName; - else - szFaceName = pStream->fonttbl[0].szFaceName; - for (i = 0; i < pStream->nFontTblLen; i++) { - if (szFaceName == pStream->fonttbl[i].szFaceName - || !lstrcmpW(szFaceName, pStream->fonttbl[i].szFaceName)) - if (!(fmt->dwMask & CFM_CHARSET) - || fmt->bCharSet == pStream->fonttbl[i].bCharSet) - break; - } - if (i < pStream->nFontTblLen) + if (fmt->dwMask & CFM_FACE || fmt->dwMask & CFM_CHARSET) + { + if (find_font_in_fonttbl( pStream, fmt, &i )) { if (i != pStream->nDefaultFont) sprintf(props + strlen(props), "\\f%u", i); -- 2.8.2 From huw at codeweavers.com Wed Oct 12 06:58:51 2016 From: huw at codeweavers.com (Huw Davies) Date: Wed, 12 Oct 2016 12:58:51 +0100 Subject: [PATCH 3/5] riched20: Add a helper to find a colour in the colour table. Message-ID: <1476273533-10193-3-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/writer.c | 62 ++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index 838168e..e7d340a 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -277,6 +277,23 @@ static void add_color_to_colortbl( ME_OutStream *stream, COLORREF color ) } } +static BOOL find_color_in_colortbl( ME_OutStream *stream, COLORREF color, unsigned int *idx ) +{ + int i; + + *idx = 0; + for (i = 1; i < stream->nColorTblLen; i++) + { + if (stream->colortbl[i] == color) + { + *idx = i; + break; + } + } + + return i < stream->nFontTblLen; +} + static BOOL ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, ME_DisplayItem *pLastRun) @@ -391,17 +408,13 @@ ME_StreamOutRTFTableProps(ME_TextEditor *editor, ME_OutStream *pStream, { if (borders[i]->width) { - unsigned int j; + unsigned int idx; COLORREF crColor = borders[i]->colorRef; sprintf(props + strlen(props), "\\clbrdr%c", sideChar[i]); sprintf(props + strlen(props), "\\brdrs"); sprintf(props + strlen(props), "\\brdrw%d", borders[i]->width); - for (j = 1; j < pStream->nColorTblLen; j++) { - if (pStream->colortbl[j] == crColor) { - sprintf(props + strlen(props), "\\brdrcf%u", j); - break; - } - } + if (find_color_in_colortbl( pStream, crColor, &idx )) + sprintf(props + strlen(props), "\\brdrcf%u", idx); } } sprintf(props + strlen(props), "\\cellx%d", cell->member.cell.nRightBoundary); @@ -423,17 +436,13 @@ ME_StreamOutRTFTableProps(ME_TextEditor *editor, ME_OutStream *pStream, { if (borders[i]->width) { - unsigned int j; + unsigned int idx; COLORREF crColor = borders[i]->colorRef; sprintf(props + strlen(props), "\\trbrdr%c", sideChar[i]); sprintf(props + strlen(props), "\\brdrs"); sprintf(props + strlen(props), "\\brdrw%d", borders[i]->width); - for (j = 1; j < pStream->nColorTblLen; j++) { - if (pStream->colortbl[j] == crColor) { - sprintf(props + strlen(props), "\\brdrcf%u", j); - break; - } - } + if (find_color_in_colortbl( pStream, crColor, &idx )) + sprintf(props + strlen(props), "\\brdrcf%u", idx); } } for (i = 0; i < pFmt->cTabCount; i++) @@ -642,26 +651,15 @@ ME_StreamOutRTFCharProps(ME_OutStream *pStream, CHARFORMAT2W *fmt) strcat(props, "\\caps"); if (fmt->dwMask & CFM_ANIMATION) sprintf(props + strlen(props), "\\animtext%u", fmt->bAnimation); - if (fmt->dwMask & CFM_BACKCOLOR) { - if (!(fmt->dwEffects & CFE_AUTOBACKCOLOR)) { - for (i = 1; i < pStream->nColorTblLen; i++) - if (pStream->colortbl[i] == fmt->crBackColor) { - sprintf(props + strlen(props), "\\cb%u", i); - break; - } - } - } + if ((fmt->dwMask & CFM_BACKCOLOR) && !(fmt->dwEffects & CFE_AUTOBACKCOLOR)) + if (find_color_in_colortbl( pStream, fmt->crBackColor, &i )) + sprintf(props + strlen(props), "\\cb%u", i); if (fmt->dwMask & CFM_BOLD && fmt->dwEffects & CFE_BOLD) strcat(props, "\\b"); - if (fmt->dwMask & CFM_COLOR) { - if (!(fmt->dwEffects & CFE_AUTOCOLOR)) { - for (i = 1; i < pStream->nColorTblLen; i++) - if (pStream->colortbl[i] == fmt->crTextColor) { - sprintf(props + strlen(props), "\\cf%u", i); - break; - } - } - } + if ((fmt->dwMask & CFM_COLOR) && !(fmt->dwEffects & CFE_AUTOCOLOR)) + if (find_color_in_colortbl( pStream, fmt->crTextColor, &i )) + sprintf(props + strlen(props), "\\cf%u", i); + /* TODO: CFM_DISABLED */ if (fmt->dwMask & CFM_EMBOSS && fmt->dwEffects & CFE_EMBOSS) strcat(props, "\\embo"); -- 2.8.2 From huw at codeweavers.com Wed Oct 12 06:58:52 2016 From: huw at codeweavers.com (Huw Davies) Date: Wed, 12 Oct 2016 12:58:52 +0100 Subject: [PATCH 4/5] riched20: Emit RTF for paragraph numbering. Message-ID: <1476273533-10193-4-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/writer.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index e7d340a..77f50e3 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -456,6 +456,76 @@ ME_StreamOutRTFTableProps(ME_TextEditor *editor, ME_OutStream *pStream, return TRUE; } +static BOOL stream_out_para_num( ME_OutStream *stream, ME_Paragraph *para, BOOL pn_dest ) +{ + static const char fmt_label[] = "{\\*\\pn\\pnlvlbody\\pnf%u\\pnindent%d\\pnstart%d%s%s}"; + static const char fmt_bullet[] = "{\\*\\pn\\pnlvlblt\\pnf%u\\pnindent%d{\\pntxtb\\'b7}}"; + static const char dec[] = "\\pndec"; + static const char lcltr[] = "\\pnlcltr"; + static const char ucltr[] = "\\pnucltr"; + static const char lcrm[] = "\\pnlcrm"; + static const char ucrm[] = "\\pnucrm"; + static const char period[] = "{\\pntxta.}"; + static const char paren[] = "{\\pntxta)}"; + static const char parens[] = "{\\pntxtb(}{\\pntxta)}"; + const char *type, *style = ""; + unsigned int idx; + + find_font_in_fonttbl( stream, ¶->para_num.style->fmt, &idx ); + + if (!ME_StreamOutPrint( stream, "{\\pntext\\f%u ", idx )) return FALSE; + if (!ME_StreamOutRTFText( stream, para->para_num.text->szData, para->para_num.text->nLen )) + return FALSE; + if (!ME_StreamOutPrint( stream, "\\tab}" )) return FALSE; + + if (!pn_dest) return TRUE; + + if (para->fmt.wNumbering == PFN_BULLET) + { + if (!ME_StreamOutPrint( stream, fmt_bullet, idx, para->fmt.wNumberingTab )) + return FALSE; + } + else + { + switch (para->fmt.wNumbering) + { + case PFN_ARABIC: + default: + type = dec; + break; + case PFN_LCLETTER: + type = lcltr; + break; + case PFN_UCLETTER: + type = ucltr; + break; + case PFN_LCROMAN: + type = lcrm; + break; + case PFN_UCROMAN: + type = ucrm; + break; + } + switch (para->fmt.wNumberingStyle & 0xf00) + { + case PFNS_PERIOD: + style = period; + break; + case PFNS_PAREN: + style = paren; + break; + case PFNS_PARENS: + style = parens; + break; + } + + if (!ME_StreamOutPrint( stream, fmt_label, idx, para->fmt.wNumberingTab, + para->fmt.wNumberingStart, type, style )) + return FALSE; + } + return TRUE; +} + static BOOL ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, ME_DisplayItem *para) @@ -501,11 +571,18 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, } if (prev_para && !memcmp( fmt, &prev_para->fmt, sizeof(*fmt) )) + { + if (fmt->wNumbering) + return stream_out_para_num( pStream, ¶->member.para, FALSE ); return TRUE; + } if (!ME_StreamOutPrint(pStream, "\\pard")) return FALSE; + if (fmt->wNumbering) + if (!stream_out_para_num( pStream, ¶->member.para, TRUE )) return FALSE; + if (!editor->bEmulateVersion10) { /* v4.1 */ if (pStream->nNestingLevel > 0) strcat(props, "\\intbl"); @@ -515,7 +592,7 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, if (fmt->dwMask & PFM_TABLE && fmt->wEffects & PFE_TABLE) strcat(props, "\\intbl"); } - + /* TODO: PFM_BORDER. M$ does not emit any keywords for these properties, and * when streaming border keywords in, PFM_BORDER is set, but wBorder field is * set very different from the documentation. -- 2.8.2 From huw at codeweavers.com Wed Oct 12 06:58:53 2016 From: huw at codeweavers.com (Huw Davies) Date: Wed, 12 Oct 2016 12:58:53 +0100 Subject: [PATCH 5/5] riched20: Draw the paragraph numbering text in the correct colour. Message-ID: <1476273533-10193-5-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/paint.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c index 7c17513..b76f533 100644 --- a/dlls/riched20/paint.c +++ b/dlls/riched20/paint.c @@ -903,16 +903,19 @@ static void draw_para_number( ME_Context *c, ME_DisplayItem *p ) ME_Paragraph *para = &p->member.para; HFONT old_font; int x, y; + COLORREF old_text; if (para->fmt.wNumbering) { old_font = ME_SelectStyleFont( c, para->para_num.style ); + old_text = SetTextColor( c->hDC, get_text_color( c, para->para_num.style, FALSE ) ); x = c->pt.x + para->para_num.pt.x; y = c->pt.y + para->pt.y + para->para_num.pt.y; ExtTextOutW( c->hDC, x, y, 0, NULL, para->para_num.text->szData, para->para_num.text->nLen, NULL ); + SetTextColor( c->hDC, old_text ); ME_UnselectStyleFont( c, para->para_num.style, old_font ); } } -- 2.8.2 From hans at codeweavers.com Wed Oct 12 08:30:20 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Wed, 12 Oct 2016 15:30:20 +0200 Subject: [2/7] webservices/tests: Add more text type tests. Message-ID: <1476279025-17957-2-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/tests/writer.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index 7e65da3..465bc5a 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -1980,6 +1980,9 @@ static void test_text_types(void) static const WS_XML_INT32_TEXT val_int32 = { {WS_XML_TEXT_TYPE_INT32}, -2147483647 - 1 }; static const WS_XML_INT64_TEXT val_int64 = { {WS_XML_TEXT_TYPE_INT64}, -9223372036854775807 - 1 }; static const WS_XML_UINT64_TEXT val_uint64 = { {WS_XML_TEXT_TYPE_UINT64}, ~0 }; + static const WS_XML_DATETIME_TEXT val_datetime = { {WS_XML_TEXT_TYPE_DATETIME}, {0, WS_DATETIME_FORMAT_UTC} }; + static const WS_XML_DOUBLE_TEXT val_double = { {WS_XML_TEXT_TYPE_DOUBLE}, 1.1 }; + static const WS_XML_BASE64_TEXT val_base64 = { {WS_XML_TEXT_TYPE_BASE64}, (BYTE *)"test", 4 }; static const struct { const WS_XML_TEXT *text; @@ -1995,6 +1998,9 @@ static void test_text_types(void) { &val_int32.text, "-2147483648" }, { &val_int64.text, "-9223372036854775808" }, { &val_uint64.text, "18446744073709551615" }, + { &val_datetime.text, "0001-01-01T00:00:00Z" }, + { &val_double.text, "1.1" }, + { &val_base64.text, "dGVzdA==" }, }; HRESULT hr; ULONG i; -- 2.1.4 From hans at codeweavers.com Wed Oct 12 08:30:19 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Wed, 12 Oct 2016 15:30:19 +0200 Subject: [1/7] webservices: Strip trailing zeros from time fraction. Message-ID: <1476279025-17957-1-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/tests/writer.c | 5 ++++- dlls/webservices/writer.c | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index 3bed673..7e65da3 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -2588,6 +2588,8 @@ static void test_datetime(void) { 1, WS_DATETIME_FORMAT_UTC, S_OK, "0001-01-01T00:00:00.0000001Z" }, { 1, WS_DATETIME_FORMAT_LOCAL, S_OK, "0001-01-01T00:00:00.0000001+00:00" }, { 1, WS_DATETIME_FORMAT_NONE, S_OK, "0001-01-01T00:00:00.0000001" }, + { 10, WS_DATETIME_FORMAT_NONE, S_OK, "0001-01-01T00:00:00.000001" }, + { 1000000, WS_DATETIME_FORMAT_NONE, S_OK, "0001-01-01T00:00:00.1" }, { 0x23c34600, WS_DATETIME_FORMAT_LOCAL, S_OK, "0001-01-01T00:01:00+00:00" }, { 0x861c46800, WS_DATETIME_FORMAT_LOCAL, S_OK, "0001-01-01T01:00:00+00:00" }, { 0x430e234000, WS_DATETIME_FORMAT_LOCAL, S_OK, "0001-01-01T08:00:00+00:00" }, @@ -2636,7 +2638,8 @@ static void test_datetime(void) ok( hr == tests[i].hr, "%u: got %08x\n", i, hr ); if (hr == S_OK) { - ok( check_result( writer, tests[i].result ) || broken(check_result( writer, tests[i].result2 )), + ok( check_result( writer, tests[i].result ) || + (tests[i].result2 && broken(check_result( writer, tests[i].result2 ))), "%u: wrong result\n", i ); } } diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 619ec2b..36bf65b 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -1235,6 +1235,7 @@ static ULONG format_datetime( const WS_DATETIME *ptr, unsigned char *buf ) { static const char fmt_frac[] = ".%07u"; len += sprintf( (char *)buf + len, fmt_frac, sec_frac ); + while (buf[len - 1] == '0') len--; } if (ptr->format == WS_DATETIME_FORMAT_UTC) { -- 2.1.4 From hans at codeweavers.com Wed Oct 12 08:30:21 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Wed, 12 Oct 2016 15:30:21 +0200 Subject: [3/7] webservices: Handle nil elements in the reader. Message-ID: <1476279025-17957-3-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/reader.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index a6f5d6b..c0710de 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -4052,6 +4052,24 @@ static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping, } } +static HRESULT is_nil_element( const WS_XML_ELEMENT_NODE *elem ) +{ + static const WS_XML_STRING localname = {3, (BYTE *)"nil"}; + static const WS_XML_STRING ns = {41, (BYTE *)"http://www.w3.org/2001/XMLSchema-instance"}; + ULONG i; + + for (i = 0; i < elem->attributeCount; i++) + { + const WS_XML_UTF8_TEXT *text = (WS_XML_UTF8_TEXT *)elem->attributes[i]->value; + + if (elem->attributes[i]->isXmlNs) continue; + if (WsXmlStringEquals( elem->attributes[i]->localName, &localname, NULL ) == S_OK && + WsXmlStringEquals( elem->attributes[i]->ns, &ns, NULL ) == S_OK && + text->value.length == 4 && !memcmp( text->value.bytes, "true", 4 )) return TRUE; + } + return FALSE; +} + static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYPE type, const WS_XML_STRING *localname, const WS_XML_STRING *ns, const void *desc, WS_READ_OPTION option, WS_HEAP *heap, @@ -4064,6 +4082,8 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP case WS_ELEMENT_TYPE_MAPPING: case WS_ELEMENT_CONTENT_TYPE_MAPPING: if ((hr = read_type_next_element_node( reader, localname, ns )) != S_OK) return hr; + if ((option == WS_READ_NILLABLE_POINTER || option == WS_READ_NILLABLE_VALUE) && + is_nil_element( &reader->current->hdr )) return read_type_next_node( reader ); break; case WS_ANY_ELEMENT_TYPE_MAPPING: -- 2.1.4 From hans at codeweavers.com Wed Oct 12 08:30:22 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Wed, 12 Oct 2016 15:30:22 +0200 Subject: [4/7] webservices: WS_FIELD_OPTIONAL takes precedence over WS_FIELD_NILLABLE. Message-ID: <1476279025-17957-4-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/tests/writer.c | 20 +++++++++++++++----- dlls/webservices/writer.c | 7 ++----- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index 465bc5a..912e944 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -2122,7 +2122,7 @@ static void test_double(void) WsFreeWriter( writer ); } -static void test_field_flags(void) +static void test_field_options(void) { static const char expected[] = "-1" @@ -2130,10 +2130,10 @@ static void test_field_flags(void) HRESULT hr; WS_XML_WRITER *writer; WS_STRUCT_DESCRIPTION s; - WS_FIELD_DESCRIPTION f, f2, f3, f4, *fields[4]; + WS_FIELD_DESCRIPTION f, f2, f3, f4, f5, *fields[5]; WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL}, str_guid = {4, (BYTE *)"guid"}; WS_XML_STRING str_int32 = {5, (BYTE *)"int32"}, str_bool = {4, (BYTE *)"bool"}; - WS_XML_STRING str_xmlstr = {6, (BYTE *)"xmlstr"}; + WS_XML_STRING str_xmlstr = {6, (BYTE *)"xmlstr"}, str_str = {3, (BYTE *)"str"}; INT32 val = -1; struct test { @@ -2141,6 +2141,7 @@ static void test_field_flags(void) BOOL *bool_ptr; INT32 *int32_ptr; WS_XML_STRING xmlstr; + WCHAR *str; } test; hr = WsCreateWriter( NULL, 0, &writer, NULL ); @@ -2187,11 +2188,20 @@ static void test_field_flags(void) f4.options = WS_FIELD_NILLABLE; fields[3] = &f4; + memset( &f5, 0, sizeof(f5) ); + f5.mapping = WS_ELEMENT_FIELD_MAPPING; + f5.localName = &str_str; + f5.offset = FIELD_OFFSET(struct test, str); + f5.ns = &ns; + f5.type = WS_WSZ_TYPE; + f5.options = WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE; + fields[4] = &f5; + memset( &s, 0, sizeof(s) ); s.size = sizeof(struct test); s.alignment = TYPE_ALIGNMENT(struct test); s.fields = fields; - s.fieldCount = 4; + s.fieldCount = 5; memset( &test, 0, sizeof(test) ); test.int32_ptr = &val; @@ -2679,7 +2689,7 @@ START_TEST(writer) test_WsCopyNode(); test_text_types(); test_double(); - test_field_flags(); + test_field_options(); test_WsWriteText(); test_WsWriteArray(); test_escapes(); diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 36bf65b..b59e903 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -1952,16 +1952,13 @@ static HRESULT write_type_struct_field( struct writer *writer, const WS_FIELD_DE if (is_nil_value( value, size )) { + if (field_options & WS_FIELD_OPTIONAL) return S_OK; if (field_options & WS_FIELD_NILLABLE) { if (field_options & WS_FIELD_POINTER) option = WS_WRITE_NILLABLE_POINTER; else option = WS_WRITE_NILLABLE_VALUE; } - else - { - if (field_options & WS_FIELD_OPTIONAL) return S_OK; - return E_INVALIDARG; - } + else return E_INVALIDARG; } else { -- 2.1.4 From hans at codeweavers.com Wed Oct 12 08:30:23 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Wed, 12 Oct 2016 15:30:23 +0200 Subject: [5/7] webservices: Determine field size from write options and type size. Message-ID: <1476279025-17957-5-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/reader.c | 8 ++++++ dlls/webservices/writer.c | 68 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index c0710de..c364cff 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -3775,12 +3775,18 @@ ULONG get_type_size( WS_TYPE type, const WS_STRUCT_DESCRIPTION *desc ) case WS_GUID_TYPE: return sizeof(GUID); + case WS_STRING_TYPE: + return sizeof(WS_STRING); + case WS_WSZ_TYPE: return sizeof(WCHAR *); case WS_BYTES_TYPE: return sizeof(WS_BYTES); + case WS_XML_STRING_TYPE: + return sizeof(WS_XML_STRING); + case WS_STRUCT_TYPE: return desc->size; @@ -3813,7 +3819,9 @@ static WS_READ_OPTION get_field_read_option( WS_TYPE type, ULONG options ) case WS_DOUBLE_TYPE: case WS_DATETIME_TYPE: case WS_GUID_TYPE: + case WS_STRING_TYPE: case WS_BYTES_TYPE: + case WS_XML_STRING_TYPE: case WS_STRUCT_TYPE: case WS_ENUM_TYPE: if (options & (WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE)) return WS_READ_NILLABLE_VALUE; diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index b59e903..26ab726 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -2023,10 +2023,70 @@ static HRESULT write_type_struct_field( struct writer *writer, const WS_FIELD_DE return S_OK; } -static ULONG get_field_size( const WS_STRUCT_DESCRIPTION *desc, ULONG index ) +static WS_WRITE_OPTION get_field_write_option( WS_TYPE type, ULONG options ) { - if (index < desc->fieldCount - 1) return desc->fields[index + 1]->offset - desc->fields[index]->offset; - return desc->size - desc->fields[index]->offset; + if (options & WS_FIELD_POINTER) + { + if (options & (WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE)) return WS_WRITE_NILLABLE_POINTER; + return WS_WRITE_REQUIRED_POINTER; + } + + switch (type) + { + case WS_BOOL_TYPE: + case WS_INT8_TYPE: + case WS_INT16_TYPE: + case WS_INT32_TYPE: + case WS_INT64_TYPE: + case WS_UINT8_TYPE: + case WS_UINT16_TYPE: + case WS_UINT32_TYPE: + case WS_UINT64_TYPE: + case WS_DOUBLE_TYPE: + case WS_DATETIME_TYPE: + case WS_GUID_TYPE: + case WS_STRING_TYPE: + case WS_BYTES_TYPE: + case WS_XML_STRING_TYPE: + case WS_STRUCT_TYPE: + case WS_ENUM_TYPE: + if (options & (WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE)) return WS_WRITE_NILLABLE_VALUE; + return WS_WRITE_REQUIRED_VALUE; + + case WS_WSZ_TYPE: + case WS_DESCRIPTION_TYPE: + if (options & (WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE)) return WS_WRITE_NILLABLE_POINTER; + return WS_WRITE_REQUIRED_POINTER; + + default: + FIXME( "unhandled type %u\n", type ); + return 0; + } +} + +static ULONG get_field_size( const WS_FIELD_DESCRIPTION *desc ) +{ + WS_WRITE_OPTION option; + ULONG size; + + switch ((option = get_field_write_option( desc->type, desc->options ))) + { + case WS_WRITE_REQUIRED_POINTER: + case WS_WRITE_NILLABLE_POINTER: + size = sizeof(const void *); + break; + + case WS_WRITE_REQUIRED_VALUE: + case WS_WRITE_NILLABLE_VALUE: + size = get_type_size( desc->type, desc->typeDescription ); + break; + + default: + WARN( "unhandled option %u\n", option ); + return 0; + } + + return size; } static HRESULT write_type_struct( struct writer *writer, WS_TYPE_MAPPING mapping, @@ -2045,7 +2105,7 @@ static HRESULT write_type_struct( struct writer *writer, WS_TYPE_MAPPING mapping for (i = 0; i < desc->fieldCount; i++) { field_ptr = (const char *)ptr + desc->fields[i]->offset; - field_size = get_field_size( desc, i ); + field_size = get_field_size( desc->fields[i] ); if ((hr = write_type_struct_field( writer, desc->fields[i], field_ptr, field_size )) != S_OK) return hr; } -- 2.1.4 From hans at codeweavers.com Wed Oct 12 08:30:24 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Wed, 12 Oct 2016 15:30:24 +0200 Subject: [6/7] webservices: Fix node insertion in the reader when the current node is an end element. Message-ID: <1476279025-17957-6-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/reader.c | 25 ++++++++++++------------- dlls/webservices/webservices_private.h | 7 ++++++- dlls/webservices/writer.c | 15 +++++++++++---- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index c364cff..9a82bcd 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -1400,16 +1400,15 @@ error: return hr; } -static inline BOOL is_valid_parent( const struct node *node ) +static struct node *find_parent( struct reader *reader ) { - if (!node) return FALSE; - return node_type( node ) == WS_XML_NODE_TYPE_ELEMENT || node_type( node ) == WS_XML_NODE_TYPE_BOF; -} - -struct node *find_parent( struct node *node ) -{ - if (is_valid_parent( node )) return node; - if (is_valid_parent( node->parent )) return node->parent; + if (node_type( reader->current ) == WS_XML_NODE_TYPE_END_ELEMENT) + { + if (is_valid_parent( reader->current->parent->parent )) return reader->current->parent->parent; + return NULL; + } + else if (is_valid_parent( reader->current )) return reader->current; + else if (is_valid_parent( reader->current->parent )) return reader->current->parent; return NULL; } @@ -1468,7 +1467,7 @@ static HRESULT read_element( struct reader *reader ) } if (!len) goto error; - if (!(parent = find_parent( reader->current ))) goto error; + if (!(parent = find_parent( reader ))) goto error; hr = E_OUTOFMEMORY; if (!(node = alloc_node( WS_XML_NODE_TYPE_ELEMENT ))) goto error; @@ -1522,7 +1521,7 @@ static HRESULT read_text( struct reader *reader ) len += skip; } - if (!(parent = find_parent( reader->current ))) return WS_E_INVALID_FORMAT; + if (!(parent = find_parent( reader ))) return WS_E_INVALID_FORMAT; if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return E_OUTOFMEMORY; text = (WS_XML_TEXT_NODE *)node; @@ -1693,7 +1692,7 @@ static HRESULT read_comment( struct reader *reader ) len += skip; } - if (!(parent = find_parent( reader->current ))) return WS_E_INVALID_FORMAT; + if (!(parent = find_parent( reader ))) return WS_E_INVALID_FORMAT; if (!(node = alloc_node( WS_XML_NODE_TYPE_COMMENT ))) return E_OUTOFMEMORY; comment = (WS_XML_COMMENT_NODE *)node; @@ -1717,7 +1716,7 @@ static HRESULT read_startcdata( struct reader *reader ) if (read_cmp( reader, "current ))) return WS_E_INVALID_FORMAT; + if (!(parent = find_parent( reader ))) return WS_E_INVALID_FORMAT; if (!(node = alloc_node( WS_XML_NODE_TYPE_CDATA ))) return E_OUTOFMEMORY; if (!(endnode = alloc_node( WS_XML_NODE_TYPE_END_CDATA ))) diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h index cdaa4b5..12b7984 100644 --- a/dlls/webservices/webservices_private.h +++ b/dlls/webservices/webservices_private.h @@ -52,7 +52,6 @@ struct node struct node *alloc_node( WS_XML_NODE_TYPE ) DECLSPEC_HIDDEN; void free_node( struct node * ) DECLSPEC_HIDDEN; void destroy_nodes( struct node * ) DECLSPEC_HIDDEN; -struct node *find_parent( struct node * ) DECLSPEC_HIDDEN; HRESULT copy_node( WS_XML_READER *, struct node ** ) DECLSPEC_HIDDEN; static inline WS_XML_NODE_TYPE node_type( const struct node *node ) @@ -125,6 +124,12 @@ static inline BOOL is_nil_value( const char *value, ULONG size ) return TRUE; } +static inline BOOL is_valid_parent( const struct node *node ) +{ + if (!node) return FALSE; + return (node_type( node ) == WS_XML_NODE_TYPE_ELEMENT || node_type( node ) == WS_XML_NODE_TYPE_BOF); +} + static inline void *heap_alloc( SIZE_T size ) { return HeapAlloc( GetProcessHeap(), 0, size ); diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 26ab726..4622277 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -130,6 +130,13 @@ static void write_insert_node( struct writer *writer, struct node *parent, struc writer->current = node; } +static struct node *find_parent( struct writer *writer ) +{ + if (is_valid_parent( writer->current )) return writer->current; + if (is_valid_parent( writer->current->parent )) return writer->current->parent; + return NULL; +} + static HRESULT write_init_state( struct writer *writer ) { struct node *node; @@ -890,7 +897,7 @@ static HRESULT write_flush( struct writer *writer ) static HRESULT write_add_cdata_node( struct writer *writer ) { struct node *node, *parent; - if (!(parent = find_parent( writer->current ))) return WS_E_INVALID_FORMAT; + if (!(parent = find_parent( writer ))) return WS_E_INVALID_FORMAT; if (!(node = alloc_node( WS_XML_NODE_TYPE_CDATA ))) return E_OUTOFMEMORY; write_insert_node( writer, parent, node ); return S_OK; @@ -977,7 +984,7 @@ static HRESULT write_add_element_node( struct writer *writer, const WS_XML_STRIN struct node *node, *parent; WS_XML_ELEMENT_NODE *elem; - if (!(parent = find_parent( writer->current ))) return WS_E_INVALID_FORMAT; + if (!(parent = find_parent( writer ))) return WS_E_INVALID_FORMAT; if (!prefix && node_type( parent ) == WS_XML_NODE_TYPE_ELEMENT) { @@ -2563,7 +2570,7 @@ static HRESULT write_add_comment_node( struct writer *writer, const WS_XML_STRIN struct node *node, *parent; WS_XML_COMMENT_NODE *comment; - if (!(parent = find_parent( writer->current ))) return WS_E_INVALID_FORMAT; + if (!(parent = find_parent( writer ))) return WS_E_INVALID_FORMAT; if (!(node = alloc_node( WS_XML_NODE_TYPE_COMMENT ))) return E_OUTOFMEMORY; comment = (WS_XML_COMMENT_NODE *)node; @@ -2774,7 +2781,7 @@ HRESULT WINAPI WsCopyNode( WS_XML_WRITER *handle, WS_XML_READER *reader, WS_ERRO if (error) FIXME( "ignoring error parameter\n" ); if (!writer) return E_INVALIDARG; - if (!(parent = find_parent( writer->current ))) return WS_E_INVALID_FORMAT; + if (!(parent = find_parent( writer ))) return WS_E_INVALID_FORMAT; if ((hr = copy_node( reader, &node )) != S_OK) return hr; write_insert_node( writer, parent, node ); -- 2.1.4 From hans at codeweavers.com Wed Oct 12 08:30:25 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Wed, 12 Oct 2016 15:30:25 +0200 Subject: [7/7] webservices: Implement WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT. Message-ID: <1476279025-17957-7-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/reader.c | 109 +++++++++++++++++++++++---------- dlls/webservices/tests/reader.c | 42 ++++++++++++- dlls/webservices/webservices_private.h | 6 ++ 3 files changed, 124 insertions(+), 33 deletions(-) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 9a82bcd..9ba4dfc 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -4000,7 +4000,11 @@ static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping, char *buf; if (!desc) return E_INVALIDARG; - if (desc->structOptions) FIXME( "struct options %08x not supported\n", desc->structOptions ); + if (desc->structOptions & ~WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT) + { + FIXME( "struct options %08x not supported\n", + desc->structOptions & ~WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT ); + } switch (option) { @@ -4037,7 +4041,7 @@ static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping, return hr; } *(char **)ret = buf; - return S_OK; + break; case WS_READ_OPTIONAL_POINTER: case WS_READ_NILLABLE_POINTER: @@ -4047,16 +4051,77 @@ static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping, buf = NULL; } *(char **)ret = buf; - return S_OK; + break; case WS_READ_REQUIRED_VALUE: case WS_READ_NILLABLE_VALUE: - return hr; + if (hr != S_OK) return hr; + break; default: ERR( "unhandled read option %u\n", option ); return E_NOTIMPL; } + + if (desc->structOptions & WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT) + { + struct node *parent = find_parent( reader ); + parent->flags |= NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT; + } + return S_OK; +} + +static HRESULT start_mapping( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_XML_STRING *localname, + const WS_XML_STRING *ns ) +{ + switch (mapping) + { + case WS_ELEMENT_TYPE_MAPPING: + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + return read_type_next_element_node( reader, localname, ns ); + + case WS_ANY_ELEMENT_TYPE_MAPPING: + case WS_ATTRIBUTE_TYPE_MAPPING: + return S_OK; + + default: + FIXME( "unhandled mapping %u\n", mapping ); + return E_NOTIMPL; + } +} + +static HRESULT read_type_endelement_node( struct reader *reader ) +{ + const struct node *parent = find_parent( reader ); + HRESULT hr; + + for (;;) + { + if ((hr = read_type_next_node( reader )) != S_OK) return hr; + if (node_type( reader->current ) == WS_XML_NODE_TYPE_END_ELEMENT && reader->current->parent == parent) + { + return S_OK; + } + if (read_end_of_data( reader ) || !(parent->flags & NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT)) break; + } + + return WS_E_INVALID_FORMAT; +} + +static HRESULT end_mapping( struct reader *reader, WS_TYPE_MAPPING mapping ) +{ + switch (mapping) + { + case WS_ELEMENT_TYPE_MAPPING: + return read_type_endelement_node( reader ); + + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + return read_type_next_node( reader ); + + case WS_ATTRIBUTE_TYPE_MAPPING: + default: + return S_OK; + } } static HRESULT is_nil_element( const WS_XML_ELEMENT_NODE *elem ) @@ -4078,28 +4143,17 @@ static HRESULT is_nil_element( const WS_XML_ELEMENT_NODE *elem ) } static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYPE type, - const WS_XML_STRING *localname, const WS_XML_STRING *ns, - const void *desc, WS_READ_OPTION option, WS_HEAP *heap, - void *value, ULONG size ) + const WS_XML_STRING *localname, const WS_XML_STRING *ns, const void *desc, + WS_READ_OPTION option, WS_HEAP *heap, void *value, ULONG size ) { HRESULT hr; - switch (mapping) - { - case WS_ELEMENT_TYPE_MAPPING: - case WS_ELEMENT_CONTENT_TYPE_MAPPING: - if ((hr = read_type_next_element_node( reader, localname, ns )) != S_OK) return hr; - if ((option == WS_READ_NILLABLE_POINTER || option == WS_READ_NILLABLE_VALUE) && - is_nil_element( &reader->current->hdr )) return read_type_next_node( reader ); - break; - - case WS_ANY_ELEMENT_TYPE_MAPPING: - case WS_ATTRIBUTE_TYPE_MAPPING: - break; + if ((hr = start_mapping( reader, mapping, localname, ns )) != S_OK) return hr; - default: - FIXME( "unhandled mapping %u\n", mapping ); - return E_NOTIMPL; + if (mapping == WS_ELEMENT_TYPE_MAPPING && is_nil_element( &reader->current->hdr )) + { + if (option != WS_READ_NILLABLE_POINTER && option != WS_READ_NILLABLE_VALUE) return WS_E_INVALID_FORMAT; + return end_mapping( reader, mapping ); } switch (type) @@ -4189,16 +4243,7 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP return E_NOTIMPL; } - switch (mapping) - { - case WS_ELEMENT_TYPE_MAPPING: - case WS_ELEMENT_CONTENT_TYPE_MAPPING: - return read_type_next_node( reader ); - - case WS_ATTRIBUTE_TYPE_MAPPING: - default: - return S_OK; - } + return end_mapping( reader, mapping ); } /************************************************************************** diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index a020c01..62ed499 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -71,6 +71,12 @@ static const char data11[] = "" ""; +static const char data11b[] = + "" + "" + "content" + ""; + static const char data12[] = "" "1" @@ -2069,12 +2075,23 @@ static void test_simple_struct_type(void) s.typeLocalName = &localname2; s.typeNs = &ns; - test = NULL; prepare_struct_type_test( reader, "testtest2" ); hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL ); ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + prepare_struct_type_test( reader, "testtest2" ); + hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + + s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT; + prepare_struct_type_test( reader, "testtest2" ); + hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + s.structOptions = 0; + test = NULL; prepare_struct_type_test( reader, "test" ); hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, @@ -2815,6 +2832,29 @@ static void test_complex_struct_type(void) ok( hr == S_OK, "got %08x\n", hr ); ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType ); + /* trailing content */ + prepare_struct_type_test( reader, data11b ); + hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + s.structOptions = WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT; + hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType ); + + prepare_struct_type_test( reader, data11b ); + hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + s.structOptions = 0; + hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), error ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + WsFreeReader( reader ); WsFreeHeap( heap ); WsFreeError( error ); diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h index 12b7984..424f3fe 100644 --- a/dlls/webservices/webservices_private.h +++ b/dlls/webservices/webservices_private.h @@ -41,12 +41,18 @@ HRESULT set_output( WS_XML_WRITER * ) DECLSPEC_HIDDEN; HRESULT set_input( WS_XML_READER *, char *, ULONG ) DECLSPEC_HIDDEN; ULONG get_type_size( WS_TYPE, const WS_STRUCT_DESCRIPTION * ) DECLSPEC_HIDDEN; +enum node_flag +{ + NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT = 0x1, +}; + struct node { WS_XML_ELEMENT_NODE hdr; struct list entry; struct node *parent; struct list children; + ULONG flags; }; struct node *alloc_node( WS_XML_NODE_TYPE ) DECLSPEC_HIDDEN; -- 2.1.4 From hverbeet at codeweavers.com Wed Oct 12 08:55:30 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Wed, 12 Oct 2016 15:55:30 +0200 Subject: [PATCH] d2d1: Implement GetDesktopDpi() In-Reply-To: <20161011204052.25775-1-nsivov@codeweavers.com> References: <20161011204052.25775-1-nsivov@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From jacek at codeweavers.com Wed Oct 12 10:11:34 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 12 Oct 2016 17:11:34 +0200 Subject: [PATCH 1/2] ws2_32: Pass completion routing to NtDeviceIoControlFile in server_ioctl_sock only if caller provided completion routine. Message-ID: Otherwise we're always doing non-blocking calls, preventing server from doing the right thing (and in actually doing the opposite in WS_SIO_ADDRESS_LIST_CHANGE case). Signed-off-by: Jacek Caban --- dlls/ws2_32/socket.c | 27 ++++++++++++++++++--------- dlls/ws2_32/tests/sock.c | 2 -- server/sock.c | 2 +- 3 files changed, 19 insertions(+), 12 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-ws2_32-Pass-completion-routing-to-NtDeviceIoControlFi.diff Type: text/x-patch Size: 3073 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 12 10:11:50 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 12 Oct 2016 17:11:50 +0200 Subject: [PATCH 2/2] server: Create ifchange async queue on socket fd. Message-ID: Signed-off-by: Jacek Caban --- dlls/ws2_32/tests/sock.c | 30 +++++++++++++++++++++++++++++- server/sock.c | 10 +++++----- 2 files changed, 34 insertions(+), 6 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-server-Create-ifchange-async-queue-on-socket-fd.diff Type: text/x-patch Size: 3966 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 12 10:13:52 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 12 Oct 2016 17:13:52 +0200 Subject: ntdll/tests: Added a test of using NtCancelIoEx on iosb associated with pipe listening. Message-ID: <11d3b392-8e3d-79a3-774b-34406e325321@codeweavers.com> This is resend of a patch from my previous series. The patch is not dependent on the series. Signed-off-by: Jacek Caban --- dlls/ntdll/tests/pipe.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-ntdll-tests-Added-a-test-of-using-NtCancelIoEx-on-ios.diff Type: text/x-patch Size: 1993 bytes Desc: not available URL: From mail at colinfinck.de Wed Oct 12 10:14:11 2016 From: mail at colinfinck.de (Colin Finck) Date: Wed, 12 Oct 2016 17:14:11 +0200 Subject: [PATCH] rpcrt4: Implement RpcBindingServerFromClient and populate NetworkAddr for each transport. Add more thorough testing for this function. Message-ID: <1476285251-593-1-git-send-email-mail@colinfinck.de> Fixes https://bugs.winehq.org/show_bug.cgi?id=38766 From: Christoph von Wittich Signed-off-by: Colin Finck --- dlls/rpcrt4/rpc_binding.c | 22 ++++++++++++++++++---- dlls/rpcrt4/rpc_transport.c | 34 ++++++++++++++++++++++++++++++++-- dlls/rpcrt4/tests/server.c | 33 ++++++++++++++++++++++----------- 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/dlls/rpcrt4/rpc_binding.c b/dlls/rpcrt4/rpc_binding.c index 7212a18..07eddbe 100644 --- a/dlls/rpcrt4/rpc_binding.c +++ b/dlls/rpcrt4/rpc_binding.c @@ -1636,11 +1636,25 @@ RpcBindingInqAuthClientExW( RPC_BINDING_HANDLE ClientBinding, RPC_AUTHZ_HANDLE * /*********************************************************************** * RpcBindingServerFromClient (RPCRT4.@) */ - -RPC_STATUS RPC_ENTRY RpcBindingServerFromClient(RPC_BINDING_HANDLE ClientBinding, RPC_BINDING_HANDLE *ServerBinding) +RPCRTAPI RPC_STATUS RPC_ENTRY +RpcBindingServerFromClient(RPC_BINDING_HANDLE ClientBinding, RPC_BINDING_HANDLE* ServerBinding) { - FIXME("%p %p: stub\n", ClientBinding, ServerBinding); - return RPC_S_INVALID_BINDING; + RpcBinding* bind = ClientBinding; + RpcBinding* NewBinding; + + if (!bind) + bind = I_RpcGetCurrentCallHandle(); + + if (!bind->server) + return RPC_S_INVALID_BINDING; + + RPCRT4_AllocBinding(&NewBinding, TRUE); + NewBinding->Protseq = RPCRT4_strdupA(bind->Protseq); + NewBinding->NetworkAddr = RPCRT4_strdupA(bind->NetworkAddr); + + *ServerBinding = NewBinding; + + return RPC_S_OK; } /*********************************************************************** diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c index b2fbf9b..cc9471d 100644 --- a/dlls/rpcrt4/rpc_transport.c +++ b/dlls/rpcrt4/rpc_transport.c @@ -388,6 +388,7 @@ static void rpcrt4_conn_np_handoff(RpcConnection_np *old_npc, RpcConnection_np * static RPC_STATUS rpcrt4_ncacn_np_handoff(RpcConnection *old_conn, RpcConnection *new_conn) { + DWORD cbComputerName = MAX_COMPUTERNAME_LENGTH + 1; RPC_STATUS status; LPSTR pname; @@ -397,6 +398,16 @@ static RPC_STATUS rpcrt4_ncacn_np_handoff(RpcConnection *old_conn, RpcConnection status = rpcrt4_conn_create_pipe(old_conn, pname); I_RpcFree(pname); + /* Store the local computer name as the NetworkAddr for ncacn_np as long as + * we don't support named pipes over the network. */ + FIXME("Using local computer name as NetworkAddr\n"); + new_conn->NetworkAddr = HeapAlloc(GetProcessHeap(), 0, cbComputerName); + if (!GetComputerNameA(new_conn->NetworkAddr, &cbComputerName)) + { + ERR("Failed to retrieve the computer name, error %u\n", GetLastError()); + return RPC_S_OUT_OF_RESOURCES; + } + return status; } @@ -429,6 +440,7 @@ static RPC_STATUS rpcrt4_ncalrpc_np_is_server_listening(const char *endpoint) static RPC_STATUS rpcrt4_ncalrpc_handoff(RpcConnection *old_conn, RpcConnection *new_conn) { + DWORD cbComputerName = MAX_COMPUTERNAME_LENGTH + 1; RPC_STATUS status; LPSTR pname; @@ -439,7 +451,15 @@ static RPC_STATUS rpcrt4_ncalrpc_handoff(RpcConnection *old_conn, RpcConnection pname = ncalrpc_pipe_name(old_conn->Endpoint); status = rpcrt4_conn_create_pipe(old_conn, pname); I_RpcFree(pname); - + + /* Store the local computer name as the NetworkAddr for ncalrpc. */ + new_conn->NetworkAddr = HeapAlloc(GetProcessHeap(), 0, cbComputerName); + if (!GetComputerNameA(new_conn->NetworkAddr, &cbComputerName)) + { + ERR("Failed to retrieve the computer name, error %u\n", GetLastError()); + return RPC_S_OUT_OF_RESOURCES; + } + return status; } @@ -1479,10 +1499,20 @@ static RPC_STATUS rpcrt4_conn_tcp_handoff(RpcConnection *old_conn, RpcConnection ERR("Failed to accept a TCP connection: error %d\n", ret); return RPC_S_OUT_OF_RESOURCES; } + nonblocking = 1; ioctlsocket(ret, FIONBIO, &nonblocking); client->sock = ret; - TRACE("Accepted a new TCP connection\n"); + + client->common.NetworkAddr = HeapAlloc(GetProcessHeap(), 0, INET6_ADDRSTRLEN); + ret = getnameinfo((struct sockaddr*)&address, addrsize, client->common.NetworkAddr, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST); + if (ret != 0) + { + ERR("Failed to retrieve the IP address, error %d\n", ret); + return RPC_S_OUT_OF_RESOURCES; + } + + TRACE("Accepted a new TCP connection from %s\n", client->common.NetworkAddr); return RPC_S_OK; } diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index f9a5a96..ee28703 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -745,29 +745,40 @@ void __cdecl s_context_handle_test(void) binding = NULL; status = RpcBindingServerFromClient(NULL, &binding); - todo_wine - { - ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status); - ok(binding != NULL, "binding is NULL\n"); - } + ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status); + ok(binding != NULL, "binding is NULL\n"); if (status == RPC_S_OK && binding != NULL) { unsigned char* string_binding = NULL; - unsigned char* computer_name = NULL; + unsigned char* object_uuid = NULL; + unsigned char* protseq = NULL; + unsigned char* network_address = NULL; + unsigned char* endpoint = NULL; + unsigned char* network_options = NULL; status = RpcBindingToStringBindingA(binding, &string_binding); - ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status); ok(string_binding != NULL, "string_binding is NULL\n"); - status = RpcStringBindingParseA(string_binding, NULL, NULL, &computer_name, NULL, NULL); - + status = RpcStringBindingParseA(string_binding, &object_uuid, &protseq, &network_address, &endpoint, &network_options); ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status); - ok(computer_name != NULL, "computer_name is NULL\n"); + ok(protseq != NULL && *protseq != '\0', "protseq is %s\n", protseq); + ok(network_address != NULL && *network_address != '\0', "network_address is %s\n", network_address); + + todo_wine + { + ok(object_uuid != NULL && *object_uuid == '\0', "object_uuid is %s\n", object_uuid); + ok(endpoint != NULL && *endpoint == '\0', "endpoint is %s\n", endpoint); + ok(network_options != NULL && *network_options == '\0', "network_options is %s\n", network_options); + } RpcStringFreeA(&string_binding); - RpcStringFreeA(&computer_name); + RpcStringFreeA(&object_uuid); + RpcStringFreeA(&protseq); + RpcStringFreeA(&network_address); + RpcStringFreeA(&endpoint); + RpcStringFreeA(&network_options); RpcBindingFree(&binding); } } -- 1.9.1 From aric at codeweavers.com Wed Oct 12 10:31:08 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 12 Oct 2016 17:31:08 +0200 Subject: [PATCH v2] winebus.sys: Implement IOCTL_HID_GET_STRING for hidraw Message-ID: v2: Suggestion from Sebastian Lackner Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_udev.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ dlls/winebus.sys/main.c | 11 ++++++ 3 files changed, 93 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: v2-0001-winebus.sys-Implement-IOCTL_HID_GET_STRING-for-hidr.txt Type: text/x-patch Size: 4621 bytes Desc: not available URL: From aric at codeweavers.com Wed Oct 12 10:38:00 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 12 Oct 2016 17:38:00 +0200 Subject: [PATCH v2 3/3] include: Define IoSkipCurrentIrpStackLocation Message-ID: v2: Suggestions from Sebastian Lackner Signed-off-by: Aric Stewart --- include/ddk/wdm.h | 4 ++++ 1 file changed, 4 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: v2-0003-include-Define-IoSkipCurrentIrpStackLocation.txt Type: text/x-patch Size: 1560 bytes Desc: not available URL: From sebastian at fds-team.de Wed Oct 12 10:46:13 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Wed, 12 Oct 2016 17:46:13 +0200 Subject: [1/2] winehid.sys: Add HID minidriver. (v2) Message-ID: <631aa9ff-ee35-e66b-a0d7-00c59138d35a@fds-team.de> From: Aric Stewart Signed-off-by: Aric Stewart Signed-off-by: Sebastian Lackner --- Changes in v2: * Avoid unnecessary ntoskrnl import. * Remove unnecessary NONAMELESSUNION define. * Change debug channel to "hid". I don't think we really need a separate one just for two or three functions related to HID handling. * Actually TRACE both arguments passed to DriverEntry. * Return STATUS_SUCCESS (otherwise the driver fails loading). * Rename service name "WineHIDMinidriver" -> "WineHID". MAINTAINERS | 1 + configure.ac | 1 + dlls/winehid.sys/Makefile.in | 5 +++++ dlls/winehid.sys/main.c | 38 ++++++++++++++++++++++++++++++++++++++ dlls/winehid.sys/winehid.sys.spec | 1 + loader/wine.inf.in | 14 ++++++++++++++ 6 files changed, 60 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 4a7191c..55a7834 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -122,6 +122,7 @@ HID support M: Aric Stewart F: dlls/hid/ F: dlls/hidclass.sys/ +F: dlls/winehid.sys/ HTML rendering (Gecko) M: Jacek Caban diff --git a/configure.ac b/configure.ac index 78c5a02..964c593 100644 --- a/configure.ac +++ b/configure.ac @@ -3425,6 +3425,7 @@ WINE_CONFIG_DLL(winecoreaudio.drv) WINE_CONFIG_LIB(winecrt0) WINE_CONFIG_DLL(wined3d,,[implib]) WINE_CONFIG_DLL(winegstreamer) +WINE_CONFIG_DLL(winehid.sys) WINE_CONFIG_DLL(winejoystick.drv) WINE_CONFIG_DLL(winemac.drv,,[clean]) WINE_CONFIG_DLL(winemapi) diff --git a/dlls/winehid.sys/Makefile.in b/dlls/winehid.sys/Makefile.in new file mode 100644 index 0000000..d4ca3dd --- /dev/null +++ b/dlls/winehid.sys/Makefile.in @@ -0,0 +1,5 @@ +MODULE = winehid.sys +EXTRADLLFLAGS = -Wb,--subsystem,native + +C_SRCS = \ + main.c diff --git a/dlls/winehid.sys/main.c b/dlls/winehid.sys/main.c new file mode 100644 index 0000000..7ab9267 --- /dev/null +++ b/dlls/winehid.sys/main.c @@ -0,0 +1,38 @@ +/* + * WINE Hid minidriver + * + * Copyright 2016 Aric Stewart + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "ddk/wdm.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(hid); + +NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path) +{ + TRACE("(%p, %s)\n", driver, debugstr_w(path->Buffer)); + + return STATUS_SUCCESS; +} diff --git a/dlls/winehid.sys/winehid.sys.spec b/dlls/winehid.sys/winehid.sys.spec new file mode 100644 index 0000000..76421d7 --- /dev/null +++ b/dlls/winehid.sys/winehid.sys.spec @@ -0,0 +1 @@ +# nothing to export diff --git a/loader/wine.inf.in b/loader/wine.inf.in index a92a9fe..fcf9c4a 100644 --- a/loader/wine.inf.in +++ b/loader/wine.inf.in @@ -131,6 +131,7 @@ AddService=LanmanServer,0,LanmanServerService AddService=FontCache,0,FontCacheService AddService=Schedule,0,TaskSchedulerService AddService=WineBus,0,WineBusService +AddService=WineHID,0,WineHIDService [DefaultInstall.NT.Services] AddService=BITS,0,BITSService @@ -146,6 +147,7 @@ AddService=LanmanServer,0,LanmanServerService AddService=FontCache,0,FontCacheService AddService=Schedule,0,TaskSchedulerService AddService=WineBus,0,WineBusService +AddService=WineHID,0,WineHIDService [DefaultInstall.ntamd64.Services] AddService=BITS,0,BITSService @@ -161,6 +163,7 @@ AddService=LanmanServer,0,LanmanServerService AddService=FontCache,0,FontCacheService AddService=Schedule,0,TaskSchedulerService AddService=WineBus,0,WineBusService +AddService=WineHID,0,WineHIDService [Strings] MciExtStr="Software\Microsoft\Windows NT\CurrentVersion\MCI Extensions" @@ -2530,6 +2533,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 12,,ndis.sys,- 12,,tdi.sys,- 12,,winebus.sys,- +12,,winehid.sys,- ; skip .NET fake dlls in Wine Mono package 11,,aspnet_regiis.exe,- 11,,ngen.exe,- @@ -2573,6 +2577,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 12,,ndis.sys 12,,tdi.sys 12,,winebus.sys +12,,winehid.sys ; skip .NET fake dlls in Wine Mono package 11,,aspnet_regiis.exe,- 11,,ngen.exe,- @@ -3198,6 +3203,15 @@ ServiceType=1 StartType=3 ErrorControl=1 +[WineHIDService] +Description="Wine HID Minidriver" +DisplayName="Wine HID" +ServiceBinary="%12%\winehid.sys" +LoadOrderGroup="WinePlugPlay" +ServiceType=1 +StartType=3 +ErrorControl=1 + [SpoolerService] Description="Loads files to memory for later printing" DisplayName="Print Spooler" -- 2.9.0 From sebastian at fds-team.de Wed Oct 12 10:46:17 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Wed, 12 Oct 2016 17:46:17 +0200 Subject: [2/2] winehid.sys: Register as a HID minidriver. (v2) Message-ID: <02d24bf4-604a-7b9f-0ef5-04d48a0693fc@fds-team.de> From: Aric Stewart Signed-off-by: Aric Stewart Signed-off-by: Sebastian Lackner --- Changes in v2: * TRACE arguments of add_device. * Declare HID_MINIDRIVER_REGISTRATION directly in DriverEntry (it does not seem to be used anywhere else, so why static?) * Pass through NTSTATUS from HidRegisterMinidriver. dlls/winehid.sys/Makefile.in | 1 + dlls/winehid.sys/main.c | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/dlls/winehid.sys/Makefile.in b/dlls/winehid.sys/Makefile.in index d4ca3dd..ad7881e 100644 --- a/dlls/winehid.sys/Makefile.in +++ b/dlls/winehid.sys/Makefile.in @@ -1,4 +1,5 @@ MODULE = winehid.sys +IMPORTS = hidclass EXTRADLLFLAGS = -Wb,--subsystem,native C_SRCS = \ diff --git a/dlls/winehid.sys/main.c b/dlls/winehid.sys/main.c index 7ab9267..cdef3c5 100644 --- a/dlls/winehid.sys/main.c +++ b/dlls/winehid.sys/main.c @@ -26,13 +26,30 @@ #include "winbase.h" #include "winternl.h" #include "ddk/wdm.h" +#include "ddk/hidport.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(hid); +static NTSTATUS WINAPI add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *device) +{ + TRACE("(%p, %p)\n", driver, device); + return STATUS_SUCCESS; +} + NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path) { + HID_MINIDRIVER_REGISTRATION registration; + TRACE("(%p, %s)\n", driver, debugstr_w(path->Buffer)); - return STATUS_SUCCESS; + driver->DriverExtension->AddDevice = add_device; + + memset(®istration, 0, sizeof(registration)); + registration.DriverObject = driver; + registration.RegistryPath = path; + registration.DeviceExtensionSize = sizeof(HID_DEVICE_EXTENSION); + registration.DevicesArePolled = FALSE; + + return HidRegisterMinidriver(®istration); } -- 2.9.0 From sebastian at fds-team.de Wed Oct 12 11:01:55 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Wed, 12 Oct 2016 18:01:55 +0200 Subject: include: Define IoSkipCurrentIrpStackLocation. (v3) Message-ID: <4beb7e60-2175-a6fb-512c-f2b9addc5d49@fds-team.de> From: Aric Stewart Signed-off-by: Aric Stewart Signed-off-by: Sebastian Lackner --- Changes in v3: * Remove unnecessary (). include/ddk/wdm.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 5602f7d..74251fc 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1175,17 +1175,21 @@ NTSTATUS WINAPI ObCloseHandle(IN HANDLE handle); # ifdef NONAMELESSSTRUCT # define IoGetCurrentIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.s.u2.CurrentStackLocation) # define IoGetNextIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.s.u2.CurrentStackLocation - 1) +# define IoSkipCurrentIrpStackLocation(_Irp) {(_Irp)->Tail.Overlay.s.u2.CurrentStackLocation++; (_Irp)->CurrentLocation++;} # else # define IoGetCurrentIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.u2.CurrentStackLocation) # define IoGetNextIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.u2.CurrentStackLocation - 1) +# define IoSkipCurrentIrpStackLocation(_Irp) {(_Irp)->Tail.Overlay.u2.CurrentStackLocation++; (_Irp)->CurrentLocation++;} # endif #else # ifdef NONAMELESSSTRUCT # define IoGetCurrentIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.s.CurrentStackLocation) # define IoGetNextIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.s.CurrentStackLocation - 1) +# define IoSkipCurrentIrpStackLocation(_Irp) {(_Irp)->Tail.Overlay.s.CurrentStackLocation++; (_Irp)->CurrentLocation++;} # else # define IoGetCurrentIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.CurrentStackLocation) # define IoGetNextIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.CurrentStackLocation - 1) +# define IoSkipCurrentIrpStackLocation(_Irp) {(_Irp)->Tail.Overlay.CurrentStackLocation++; (_Irp)->CurrentLocation++;} # endif #endif -- 2.9.0 From aric at codeweavers.com Wed Oct 12 11:19:45 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 12 Oct 2016 18:19:45 +0200 Subject: [PATCH v2 4/4] winehid: Implement handing internal ioctls Message-ID: Mostly by passing them to the bus driver where platform specific actions happen v2: Suggestion from Sebastian Lackner Signed-off-by: Aric Stewart --- dlls/winehid.sys/main.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: v2-0004-winehid-Implement-handing-internal-ioctls.txt Type: text/x-patch Size: 2643 bytes Desc: not available URL: From sebastian at fds-team.de Wed Oct 12 11:53:55 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Wed, 12 Oct 2016 18:53:55 +0200 Subject: ntoskrnl.exe: Don't transfer back input buffer for IRP_MJ_WRITE requests. Message-ID: <662ea1b2-4e0e-01ca-2d69-7587ddcd9460@fds-team.de> Signed-off-by: Sebastian Lackner --- For IRP_MJ_WRITE requests UserBuffer has a different meaning, and there is no need to transfer the content back to the wineserver. Tests show that the irp->Flags are not set when using IoBuildSynchronousFsdRequest to build an IRP. dlls/ntoskrnl.exe/ntoskrnl.c | 13 ++++++++++--- include/ddk/wdm.h | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 909bf6f..5d423e0 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -176,12 +176,15 @@ static HANDLE get_device_manager(void) static NTSTATUS WINAPI dispatch_irp_completion( DEVICE_OBJECT *device, IRP *irp, void *context ) { FILE_OBJECT *file = irp->Tail.Overlay.OriginalFileObject; + HANDLE irp_handle = context; void *out_buff = irp->UserBuffer; - HANDLE handle = context; + + if (irp->Flags & IRP_WRITE_OPERATION) + out_buff = NULL; /* do not transfer back input buffer */ SERVER_START_REQ( set_irp_result ) { - req->handle = wine_server_obj_handle( handle ); + req->handle = wine_server_obj_handle( irp_handle ); req->status = irp->IoStatus.u.Status; req->file_ptr = wine_server_client_ptr( file ); if (irp->IoStatus.u.Status >= 0) @@ -193,7 +196,7 @@ static NTSTATUS WINAPI dispatch_irp_completion( DEVICE_OBJECT *device, IRP *irp, } SERVER_END_REQ; - HeapFree( GetProcessHeap(), 0, out_buff ); + HeapFree( GetProcessHeap(), 0, irp->UserBuffer ); return STATUS_SUCCESS; } @@ -248,6 +251,7 @@ static NTSTATUS dispatch_create( const irp_params_t *params, void *in_buff, ULON irp->UserIosb = NULL; irp->UserEvent = NULL; + irp->Flags |= IRP_CREATE_OPERATION; dispatch_irp( device, irp, irp_handle ); return STATUS_SUCCESS; @@ -285,6 +289,7 @@ static NTSTATUS dispatch_close( const irp_params_t *params, void *in_buff, ULONG irp->UserIosb = NULL; irp->UserEvent = NULL; + irp->Flags |= IRP_CLOSE_OPERATION; dispatch_irp( device, irp, irp_handle ); HeapFree( GetProcessHeap(), 0, file ); /* FIXME: async close processing not supported */ @@ -325,6 +330,7 @@ static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG irpsp = IoGetNextIrpStackLocation( irp ); irpsp->Parameters.Read.Key = params->read.key; + irp->Flags |= IRP_READ_OPERATION; dispatch_irp( device, irp, irp_handle ); return STATUS_SUCCESS; @@ -358,6 +364,7 @@ static NTSTATUS dispatch_write( const irp_params_t *params, void *in_buff, ULONG irpsp = IoGetNextIrpStackLocation( irp ); irpsp->Parameters.Write.Key = params->write.key; + irp->Flags |= IRP_WRITE_OPERATION; dispatch_irp( device, irp, irp_handle ); return STATUS_SUCCESS; diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 5602f7d..d6ee235 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -457,6 +457,23 @@ typedef struct _IRP { } IRP; typedef struct _IRP *PIRP; +#define IRP_NOCACHE 0x0001 +#define IRP_PAGING_IO 0x0002 +#define IRP_MOUNT_COMPLETION 0x0002 +#define IRP_SYNCHRONOUS_API 0x0004 +#define IRP_ASSOCIATED_IRP 0x0008 +#define IRP_BUFFERED_IO 0x0010 +#define IRP_DEALLOCATE_BUFFER 0x0020 +#define IRP_INPUT_OPERATION 0x0040 +#define IRP_SYNCHRONOUS_PAGING_IO 0x0040 +#define IRP_CREATE_OPERATION 0x0080 +#define IRP_READ_OPERATION 0x0100 +#define IRP_WRITE_OPERATION 0x0200 +#define IRP_CLOSE_OPERATION 0x0400 +#define IRP_DEFER_IO_COMPLETION 0x0800 +#define IRP_OB_QUERY_NAME 0x1000 +#define IRP_HOLD_DEVICE_QUEUE 0x2000 + typedef VOID (WINAPI *PINTERFACE_REFERENCE)( PVOID Context); -- 2.9.0 From sebastian at fds-team.de Wed Oct 12 17:46:34 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Thu, 13 Oct 2016 00:46:34 +0200 Subject: [1/2] ntoskrnl.exe: Add support for async close processing. Message-ID: Signed-off-by: Sebastian Lackner --- dlls/ntoskrnl.exe/ntoskrnl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 5d423e0..f3b6913 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -196,6 +196,12 @@ static NTSTATUS WINAPI dispatch_irp_completion( DEVICE_OBJECT *device, IRP *irp, } SERVER_END_REQ; + if (irp->Flags & IRP_CLOSE_OPERATION) + { + HeapFree( GetProcessHeap(), 0, file ); + irp->Tail.Overlay.OriginalFileObject = NULL; + } + HeapFree( GetProcessHeap(), 0, irp->UserBuffer ); return STATUS_SUCCESS; } @@ -292,7 +298,6 @@ static NTSTATUS dispatch_close( const irp_params_t *params, void *in_buff, ULONG irp->Flags |= IRP_CLOSE_OPERATION; dispatch_irp( device, irp, irp_handle ); - HeapFree( GetProcessHeap(), 0, file ); /* FIXME: async close processing not supported */ return STATUS_SUCCESS; } -- 2.9.0 From sebastian at fds-team.de Wed Oct 12 17:51:48 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Thu, 13 Oct 2016 00:51:48 +0200 Subject: [2/2] ntoskrnl.exe: Fix management of input/output buffers in dispatch handlers. Message-ID: <182d7080-710e-d47d-df36-9608ed8deff3@fds-team.de> Signed-off-by: Sebastian Lackner --- Initially I was planning to reuse the in_buff where possible, however I came to the conclusion that this is not worth the effort. We could only do that for less- frequently used requests, but usually not for dispatch_ioctl. Now, all dispatch_*() functions have to release in_buff (either immediately or deferred), if they return STATUS_SUCCESS. Read/Write uses IRP_DEALLOCATE_BUFFER to let IoCompleteRequest do that. Ioctls are a bit more complicated - if a separate output buffer (UserBuffer) is used it is deallocated in the completion routine. After sending a request to the dispatcher, wine_ntoskrnl_main_loop now allocates a fresh in_buff with default size (based on the assumption that most of the packets will be rather small, and that there is no need to keep a huge buffer size). This patch also fixes a small bug in wine_ntoskrnl_main_loop. in_size was assigned even when the wineserver returned STATUS_PENDING. When the following request has in_size != 0 this required an unnecessary additional roundtrip. dlls/ntoskrnl.exe/ntoskrnl.c | 47 +++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index f3b6913..974f946 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -202,7 +202,11 @@ static NTSTATUS WINAPI dispatch_irp_completion( DEVICE_OBJECT *device, IRP *irp, irp->Tail.Overlay.OriginalFileObject = NULL; } - HeapFree( GetProcessHeap(), 0, irp->UserBuffer ); + if (irp->UserBuffer != irp->AssociatedIrp.SystemBuffer) + { + HeapFree( GetProcessHeap(), 0, irp->UserBuffer ); + irp->UserBuffer = NULL; + } return STATUS_SUCCESS; } @@ -260,6 +264,7 @@ static NTSTATUS dispatch_create( const irp_params_t *params, void *in_buff, ULON irp->Flags |= IRP_CREATE_OPERATION; dispatch_irp( device, irp, irp_handle ); + HeapFree( GetProcessHeap(), 0, in_buff ); return STATUS_SUCCESS; } @@ -298,6 +303,7 @@ static NTSTATUS dispatch_close( const irp_params_t *params, void *in_buff, ULONG irp->Flags |= IRP_CLOSE_OPERATION; dispatch_irp( device, irp, irp_handle ); + HeapFree( GetProcessHeap(), 0, in_buff ); return STATUS_SUCCESS; } @@ -336,8 +342,10 @@ static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG irpsp->Parameters.Read.Key = params->read.key; irp->Flags |= IRP_READ_OPERATION; + irp->Flags |= IRP_DEALLOCATE_BUFFER; /* deallocate out_buff */ dispatch_irp( device, irp, irp_handle ); + HeapFree( GetProcessHeap(), 0, in_buff ); return STATUS_SUCCESS; } @@ -370,6 +378,7 @@ static NTSTATUS dispatch_write( const irp_params_t *params, void *in_buff, ULONG irpsp->Parameters.Write.Key = params->write.key; irp->Flags |= IRP_WRITE_OPERATION; + irp->Flags |= IRP_DEALLOCATE_BUFFER; /* deallocate in_buff */ dispatch_irp( device, irp, irp_handle ); return STATUS_SUCCESS; @@ -398,6 +407,7 @@ static NTSTATUS dispatch_flush( const irp_params_t *params, void *in_buff, ULONG dispatch_irp( device, irp, irp_handle ); + HeapFree( GetProcessHeap(), 0, in_buff ); return STATUS_SUCCESS; } @@ -425,6 +435,7 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG if ((params->ioctl.code & 3) == METHOD_BUFFERED) { memcpy( out_buff, in_buff, in_size ); + HeapFree( GetProcessHeap(), 0, in_buff ); in_buff = out_buff; } } @@ -439,7 +450,9 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG irp->Tail.Overlay.OriginalFileObject = file; irp->RequestorMode = UserMode; + irp->AssociatedIrp.SystemBuffer = in_buff; + irp->Flags |= IRP_DEALLOCATE_BUFFER; /* deallocate in_buff */ dispatch_irp( device, irp, irp_handle ); return STATUS_SUCCESS; @@ -490,23 +503,23 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) HANDLE irp = 0; NTSTATUS status = STATUS_SUCCESS; irp_params_t irp_params; - void *in_buff; ULONG in_size = 4096, out_size = 0; + void *in_buff = NULL; HANDLE handles[2]; request_thread = GetCurrentThreadId(); - if (!(in_buff = HeapAlloc( GetProcessHeap(), 0, in_size ))) - { - ERR( "failed to allocate buffer\n" ); - return STATUS_NO_MEMORY; - } - handles[0] = stop_event; handles[1] = manager; for (;;) { + if (!in_buff && !(in_buff = HeapAlloc( GetProcessHeap(), 0, in_size ))) + { + ERR( "failed to allocate buffer\n" ); + return STATUS_NO_MEMORY; + } + SERVER_START_REQ( get_next_device_request ) { req->manager = wine_server_obj_handle( manager ); @@ -525,13 +538,13 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) else { irp = 0; /* no previous irp */ - out_size = 0; - in_size = reply->in_size; + if (status == STATUS_BUFFER_OVERFLOW) + in_size = reply->in_size; } } SERVER_END_REQ; - switch(status) + switch (status) { case STATUS_SUCCESS: if (irp_params.major > IRP_MJ_MAXIMUM_FUNCTION || !dispatch_funcs[irp_params.major]) @@ -541,11 +554,16 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) break; } status = dispatch_funcs[irp_params.major]( &irp_params, in_buff, in_size, out_size, irp ); - if (status == STATUS_SUCCESS) irp = 0; /* status reported by IoCompleteRequest */ + if (status == STATUS_SUCCESS) + { + irp = 0; /* status reported by IoCompleteRequest */ + in_size = 4096; + in_buff = NULL; + } break; case STATUS_BUFFER_OVERFLOW: HeapFree( GetProcessHeap(), 0, in_buff ); - in_buff = HeapAlloc( GetProcessHeap(), 0, in_size ); + in_buff = NULL; /* restart with larger buffer */ break; case STATUS_PENDING: @@ -1451,6 +1469,9 @@ VOID WINAPI IoCompleteRequest( IRP *irp, UCHAR priority_boost ) } } + if (irp->Flags & IRP_DEALLOCATE_BUFFER) + HeapFree( GetProcessHeap(), 0, irp->AssociatedIrp.SystemBuffer ); + IoFreeIrp( irp ); } -- 2.9.0 From mbruni at codeweavers.com Wed Oct 12 18:04:06 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Thu, 13 Oct 2016 01:04:06 +0200 Subject: [PATCH 1/5] d3d11/tests: Make the window client rect match the d3d swapchain size. Message-ID: <1476313450-31082-1-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- dlls/d3d11/tests/d3d11.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index ed4987e..4ff7d45 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -1056,6 +1056,7 @@ static BOOL init_test_context_(unsigned int line, struct d3d11_test_context *con struct device_desc device_desc; D3D11_VIEWPORT vp; HRESULT hr; + RECT rect; memset(context, 0, sizeof(*context)); @@ -1066,8 +1067,10 @@ static BOOL init_test_context_(unsigned int line, struct d3d11_test_context *con skip_(__FILE__, line)("Failed to create device.\n"); return FALSE; } + SetRect(&rect, 0, 0, 640, 480); + AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE); context->window = CreateWindowA("static", "d3d11_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + 0, 0, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, NULL, NULL); context->swapchain = create_swapchain(context->device, context->window, NULL); hr = IDXGISwapChain_GetBuffer(context->swapchain, 0, &IID_ID3D11Texture2D, (void **)&context->backbuffer); ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr); @@ -7695,6 +7698,7 @@ static void test_swapchain_flip(void) DWORD color; HWND window; HRESULT hr; + RECT rect; static const D3D11_INPUT_ELEMENT_DESC layout_desc[] = { @@ -7774,8 +7778,10 @@ static void test_swapchain_flip(void) skip("Failed to create device, skipping tests.\n"); return; } + SetRect(&rect, 0, 0, 640, 480); + AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE); window = CreateWindowA("static", "d3d11_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + 0, 0, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, NULL, NULL); desc.buffer_count = 3; desc.swap_effect = DXGI_SWAP_EFFECT_SEQUENTIAL; desc.windowed = TRUE; -- 2.7.3 From mbruni at codeweavers.com Wed Oct 12 18:04:07 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Thu, 13 Oct 2016 01:04:07 +0200 Subject: [PATCH 2/5] d3d11/tests: Add a test for derivative shader instructions. In-Reply-To: <1476313450-31082-1-git-send-email-mbruni@codeweavers.com> References: <1476313450-31082-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1476313450-31082-2-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- dlls/d3d11/tests/d3d11.c | 241 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 4ff7d45..7ae4bd1 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -10760,6 +10760,246 @@ static void run_for_each_9_x_feature_level(void (*test_func)(const D3D_FEATURE_L test_func(feature_levels[i]); } +static void test_ddy(void) +{ + static const struct + { + struct vec4 position; + unsigned int color; + } + quad[] = + { + {{-1.0f, -1.0f, 0.0f, 1.0f}, 0x00ff0000}, + {{-1.0f, 1.0f, 0.0f, 1.0f}, 0x0000ff00}, + {{ 1.0f, -1.0f, 0.0f, 1.0f}, 0x00ff0000}, + {{ 1.0f, 1.0f, 0.0f, 1.0f}, 0x0000ff00}, + }; + static const D3D11_INPUT_ELEMENT_DESC layout_desc[] = + { + {"SV_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }; +#if 0 +struct vs_data +{ + float4 pos : SV_POSITION; + float4 color : COLOR; +}; + +void main(in struct vs_data vs_input, out struct vs_data vs_output) +{ + vs_output.pos = vs_input.pos; + vs_output.color = vs_input.color; +} +#endif + static const DWORD vs_code[] = + { + 0x43425844, 0xd5b32785, 0x35332906, 0x4d05e031, 0xf66a58af, 0x00000001, 0x00000144, 0x00000003, + 0x0000002c, 0x00000080, 0x000000d4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000044, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, + 0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, + 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, + 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x52444853, 0x00000068, 0x00010040, + 0x0000001a, 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x001010f2, 0x00000001, 0x04000067, + 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x05000036, 0x001020f2, + 0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x001020f2, 0x00000001, 0x00101e46, 0x00000001, + 0x0100003e, + }; +#if 0 +struct ps_data +{ + float4 pos : SV_POSITION; + float4 color : COLOR; +}; + +float4 main(struct ps_data ps_input) : SV_Target +{ + return ddy(ps_input.color) * 240.0 + 0.5; +} +#endif + static const DWORD ps_code_ddy[] = + { + 0x43425844, 0x423712f6, 0x786c59c2, 0xa6023c60, 0xb79faad2, 0x00000001, 0x00000138, 0x00000003, + 0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x0000007c, 0x00000040, + 0x0000001f, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000001, 0x0500000c, 0x001000f2, 0x00000000, 0x00101e46, 0x00000001, 0x0f000032, 0x001020f2, + 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x43700000, 0x43700000, 0x43700000, 0x43700000, + 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x0100003e, + }; +#if 0 +struct ps_data +{ + float4 pos : SV_POSITION; + float4 color : COLOR; +}; + +float4 main(struct ps_data ps_input) : SV_Target +{ + return ddy_coarse(ps_input.color) * 240.0 + 0.5; +} +#endif + static const DWORD ps_code_ddy_coarse[] = + { + 0x43425844, 0xbf9a31cb, 0xb42695b6, 0x629119b8, 0x6962d5dd, 0x00000001, 0x0000013c, 0x00000003, + 0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000080, 0x00000050, + 0x00000020, 0x0100086a, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, + 0x02000068, 0x00000001, 0x0500007c, 0x001000f2, 0x00000000, 0x00101e46, 0x00000001, 0x0f000032, + 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x43700000, 0x43700000, 0x43700000, + 0x43700000, 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x0100003e, + }; +#if 0 +struct ps_data +{ + float4 pos : SV_POSITION; + float4 color : COLOR; +}; + +float4 main(struct ps_data ps_input) : SV_Target +{ + return ddy_fine(ps_input.color) * 240.0 + 0.5; +} +#endif + static const DWORD ps_code_ddy_fine[] = + { + 0x43425844, 0xea6563ae, 0x3ee0da50, 0x4c2b3ef3, 0xa69a4077, 0x00000001, 0x0000013c, 0x00000003, + 0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000080, 0x00000050, + 0x00000020, 0x0100086a, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, + 0x02000068, 0x00000001, 0x0500007d, 0x001000f2, 0x00000000, 0x00101e46, 0x00000001, 0x0f000032, + 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x43700000, 0x43700000, 0x43700000, + 0x43700000, 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x0100003e, + }; + static const struct + { + D3D_FEATURE_LEVEL min_feature_level; + const DWORD *ps_code; + unsigned int ps_code_size; + } + tests[] = + { + {D3D_FEATURE_LEVEL_10_0, ps_code_ddy, sizeof(ps_code_ddy)}, + {D3D_FEATURE_LEVEL_11_0, ps_code_ddy_coarse, sizeof(ps_code_ddy_coarse)}, + {D3D_FEATURE_LEVEL_11_0, ps_code_ddy_fine, sizeof(ps_code_ddy_fine)}, + }; + static const float red[] = {1.0f, 0.0f, 0.0f, 1.0f}; + struct d3d11_test_context test_context; + D3D11_TEXTURE2D_DESC texture_desc; + D3D_FEATURE_LEVEL feature_level; + ID3D11InputLayout *input_layout; + ID3D11DeviceContext *context; + unsigned int stride, offset; + struct resource_readback rb; + ID3D11RenderTargetView *rtv; + ID3D11Texture2D *texture; + ID3D11VertexShader *vs; + ID3D11PixelShader *ps; + ID3D11Device *device; + ID3D11Buffer *vb; + unsigned int i; + DWORD color; + HRESULT hr; + + if (!init_test_context(&test_context, NULL)) + return; + + device = test_context.device; + context = test_context.immediate_context; + feature_level = ID3D11Device_GetFeatureLevel(device); + + ID3D11Texture2D_GetDesc(test_context.backbuffer, &texture_desc); + hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, &texture); + ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); + + hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)texture, NULL, &rtv); + ok(SUCCEEDED(hr), "Failed to create render target view, hr %#x.\n", hr); + + hr = ID3D11Device_CreateInputLayout(device, layout_desc, sizeof(layout_desc) / sizeof(*layout_desc), + vs_code, sizeof(vs_code), &input_layout); + ok(SUCCEEDED(hr), "Failed to create input layout, hr %#x.\n", hr); + + vb = create_buffer(device, D3D11_BIND_VERTEX_BUFFER, sizeof(quad), quad); + + hr = ID3D11Device_CreateVertexShader(device, vs_code, sizeof(vs_code), NULL, &vs); + ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); + + ID3D11DeviceContext_IASetInputLayout(context, input_layout); + ID3D11DeviceContext_IASetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + stride = sizeof(*quad); + offset = 0; + ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &vb, &stride, &offset); + ID3D11DeviceContext_VSSetShader(context, vs, NULL, 0); + + for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i) + { + if (feature_level < tests[i].min_feature_level) + { + skip("Skipping test %u, feature_level %#x lower than minimum required %#x.\n", i, + feature_level, tests[i].min_feature_level); + continue; + } + + hr = ID3D11Device_CreatePixelShader(device, tests[i].ps_code, tests[i].ps_code_size, NULL, &ps); + ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr); + + ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0); + + ID3D11DeviceContext_OMSetRenderTargets(context, 1, &rtv, NULL); + ID3D11DeviceContext_ClearRenderTargetView(context, rtv, red); + ID3D11DeviceContext_Draw(context, 4, 0); + + get_texture_readback(texture, 0, &rb); + color = get_readback_color(&rb, 320, 190); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 255, 240); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 320, 240); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 385, 240); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 320, 290); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + release_resource_readback(&rb); + + ID3D11DeviceContext_OMSetRenderTargets(context, 1, &test_context.backbuffer_rtv, NULL); + ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, red); + ID3D11DeviceContext_Draw(context, 4, 0); + + get_texture_readback(test_context.backbuffer, 0, &rb); + color = get_readback_color(&rb, 320, 190); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 255, 240); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 320, 240); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 385, 240); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 320, 290); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + release_resource_readback(&rb); + + ID3D11PixelShader_Release(ps); + } + + ID3D11VertexShader_Release(vs); + ID3D11Buffer_Release(vb); + ID3D11InputLayout_Release(input_layout); + ID3D11Texture2D_Release(texture); + ID3D11RenderTargetView_Release(rtv); + release_test_context(&test_context); +} + START_TEST(d3d11) { test_create_device(); @@ -10820,4 +11060,5 @@ START_TEST(d3d11) test_line_antialiasing_blending(); run_for_each_feature_level(test_required_format_support); run_for_each_9_x_feature_level(test_fl9_draw); + test_ddy(); } -- 2.7.3 From mbruni at codeweavers.com Wed Oct 12 18:04:08 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Thu, 13 Oct 2016 01:04:08 +0200 Subject: [PATCH 3/5] d3d10core/tests: Make the window client rect match the d3d swapchain size. In-Reply-To: <1476313450-31082-1-git-send-email-mbruni@codeweavers.com> References: <1476313450-31082-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1476313450-31082-3-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- dlls/d3d10core/tests/device.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dlls/d3d10core/tests/device.c b/dlls/d3d10core/tests/device.c index 37b08e5..886a950 100644 --- a/dlls/d3d10core/tests/device.c +++ b/dlls/d3d10core/tests/device.c @@ -920,6 +920,7 @@ static BOOL init_test_context_(unsigned int line, struct d3d10core_test_context { D3D10_VIEWPORT vp; HRESULT hr; + RECT rect; memset(context, 0, sizeof(*context)); @@ -928,8 +929,10 @@ static BOOL init_test_context_(unsigned int line, struct d3d10core_test_context skip_(__FILE__, line)("Failed to create device.\n"); return FALSE; } + SetRect(&rect, 0, 0, 640, 480); + AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE); context->window = CreateWindowA("static", "d3d10core_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + 0, 0, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, NULL, NULL); context->swapchain = create_swapchain(context->device, context->window, NULL); hr = IDXGISwapChain_GetBuffer(context->swapchain, 0, &IID_ID3D10Texture2D, (void **)&context->backbuffer); ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr); @@ -7396,6 +7399,7 @@ static void test_swapchain_flip(void) DWORD color; HWND window; HRESULT hr; + RECT rect; static const D3D10_INPUT_ELEMENT_DESC layout_desc[] = { @@ -7476,8 +7480,10 @@ static void test_swapchain_flip(void) skip("Failed to create device, skipping tests.\n"); return; } + SetRect(&rect, 0, 0, 640, 480); + AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE); window = CreateWindowA("static", "d3d10core_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, NULL, NULL, NULL, NULL); + 0, 0, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, NULL, NULL); desc.buffer_count = 3; desc.swap_effect = DXGI_SWAP_EFFECT_SEQUENTIAL; desc.windowed = TRUE; -- 2.7.3 From mbruni at codeweavers.com Wed Oct 12 18:04:09 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Thu, 13 Oct 2016 01:04:09 +0200 Subject: [PATCH 4/5] d3d10core/tests: Add a test for ddy. In-Reply-To: <1476313450-31082-1-git-send-email-mbruni@codeweavers.com> References: <1476313450-31082-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1476313450-31082-4-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- dlls/d3d10core/tests/device.c | 163 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/dlls/d3d10core/tests/device.c b/dlls/d3d10core/tests/device.c index 886a950..9f98850 100644 --- a/dlls/d3d10core/tests/device.c +++ b/dlls/d3d10core/tests/device.c @@ -9532,6 +9532,168 @@ static void test_required_format_support(void) ok(!refcount, "Device has %u references left.\n", refcount); } +static void test_ddy(void) +{ + static const struct + { + struct vec4 position; + unsigned int color; + } + quad[] = + { + {{-1.0f, -1.0f, 0.0f, 1.0f}, 0x00ff0000}, + {{-1.0f, 1.0f, 0.0f, 1.0f}, 0x0000ff00}, + {{ 1.0f, -1.0f, 0.0f, 1.0f}, 0x00ff0000}, + {{ 1.0f, 1.0f, 0.0f, 1.0f}, 0x0000ff00}, + }; + static const D3D10_INPUT_ELEMENT_DESC layout_desc[] = + { + {"SV_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0}, + }; +#if 0 +struct vs_data +{ + float4 pos : SV_POSITION; + float4 color : COLOR; +}; + +void main(in struct vs_data vs_input, out struct vs_data vs_output) +{ + vs_output.pos = vs_input.pos; + vs_output.color = vs_input.color; +} +#endif + static const DWORD vs_code[] = + { + 0x43425844, 0xd5b32785, 0x35332906, 0x4d05e031, 0xf66a58af, 0x00000001, 0x00000144, 0x00000003, + 0x0000002c, 0x00000080, 0x000000d4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000044, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, + 0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, + 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, + 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x52444853, 0x00000068, 0x00010040, + 0x0000001a, 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x001010f2, 0x00000001, 0x04000067, + 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x05000036, 0x001020f2, + 0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x001020f2, 0x00000001, 0x00101e46, 0x00000001, + 0x0100003e, + }; +#if 0 +struct ps_data +{ + float4 pos : SV_POSITION; + float4 color : COLOR; +}; + +float4 main(struct ps_data ps_input) : SV_Target +{ + return ddy(ps_input.color) * 240.0 + 0.5; +} +#endif + static const DWORD ps_code[] = + { + 0x43425844, 0x423712f6, 0x786c59c2, 0xa6023c60, 0xb79faad2, 0x00000001, 0x00000138, 0x00000003, + 0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x0000007c, 0x00000040, + 0x0000001f, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000001, 0x0500000c, 0x001000f2, 0x00000000, 0x00101e46, 0x00000001, 0x0f000032, 0x001020f2, + 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x43700000, 0x43700000, 0x43700000, 0x43700000, + 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x0100003e, + }; + static const float red[] = {1.0f, 0.0f, 0.0f, 1.0f}; + struct d3d10core_test_context test_context; + D3D10_TEXTURE2D_DESC texture_desc; + ID3D10InputLayout *input_layout; + unsigned int stride, offset; + struct resource_readback rb; + ID3D10RenderTargetView *rtv; + ID3D10Texture2D *texture; + ID3D10VertexShader *vs; + ID3D10PixelShader *ps; + ID3D10Device *device; + ID3D10Buffer *vb; + DWORD color; + HRESULT hr; + + if (!init_test_context(&test_context)) + return; + + device = test_context.device; + + ID3D10Texture2D_GetDesc(test_context.backbuffer, &texture_desc); + hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, &texture); + ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); + + hr = ID3D10Device_CreateRenderTargetView(device, (ID3D10Resource *)texture, NULL, &rtv); + ok(SUCCEEDED(hr), "Failed to create render target view, hr %#x.\n", hr); + + hr = ID3D10Device_CreateInputLayout(device, layout_desc, sizeof(layout_desc) / sizeof(*layout_desc), + vs_code, sizeof(vs_code), &input_layout); + ok(SUCCEEDED(hr), "Failed to create input layout, hr %#x.\n", hr); + + vb = create_buffer(device, D3D10_BIND_VERTEX_BUFFER, sizeof(quad), quad); + + hr = ID3D10Device_CreateVertexShader(device, vs_code, sizeof(vs_code), &vs); + ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); + + ID3D10Device_IASetInputLayout(device, input_layout); + ID3D10Device_IASetPrimitiveTopology(device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + stride = sizeof(*quad); + offset = 0; + ID3D10Device_IASetVertexBuffers(device, 0, 1, &vb, &stride, &offset); + ID3D10Device_VSSetShader(device, vs); + + hr = ID3D10Device_CreatePixelShader(device, ps_code, sizeof(ps_code), &ps); + ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr); + + ID3D10Device_PSSetShader(device, ps); + + ID3D10Device_OMSetRenderTargets(device, 1, &rtv, NULL); + ID3D10Device_ClearRenderTargetView(device, rtv, red); + ID3D10Device_Draw(device, 4, 0); + + get_texture_readback(texture, 0, &rb); + color = get_readback_color(&rb, 320, 190); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 255, 240); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 320, 240); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 385, 240); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 320, 290); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + release_resource_readback(&rb); + + ID3D10Device_OMSetRenderTargets(device, 1, &test_context.backbuffer_rtv, NULL); + ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, red); + ID3D10Device_Draw(device, 4, 0); + + get_texture_readback(test_context.backbuffer, 0, &rb); + color = get_readback_color(&rb, 320, 190); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 255, 240); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 320, 240); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 385, 240); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + color = get_readback_color(&rb, 320, 290); + ok(compare_color(color, 0x7fff007f, 1), "Got unexpected color 0x%08x.\n", color); + release_resource_readback(&rb); + + ID3D10PixelShader_Release(ps); + ID3D10VertexShader_Release(vs); + ID3D10Buffer_Release(vb); + ID3D10InputLayout_Release(input_layout); + ID3D10Texture2D_Release(texture); + ID3D10RenderTargetView_Release(rtv); + release_test_context(&test_context); +} + START_TEST(device) { test_feature_level(); @@ -9586,4 +9748,5 @@ START_TEST(device) test_face_culling(); test_line_antialiasing_blending(); test_required_format_support(); + test_ddy(); } -- 2.7.3 From mbruni at codeweavers.com Wed Oct 12 18:04:10 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Thu, 13 Oct 2016 01:04:10 +0200 Subject: [PATCH 5/5] wined3d: Cleanup user clip distances defines and fields a bit. In-Reply-To: <1476313450-31082-1-git-send-email-mbruni@codeweavers.com> References: <1476313450-31082-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1476313450-31082-5-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- dlls/wined3d/arb_program_shader.c | 13 ++++++++----- dlls/wined3d/device.c | 4 ++-- dlls/wined3d/directx.c | 4 ++-- dlls/wined3d/glsl_shader.c | 22 +++++++++++----------- dlls/wined3d/state.c | 14 +++++++------- dlls/wined3d/wined3d_private.h | 10 +++++----- 6 files changed, 35 insertions(+), 32 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index e00f981..762b8a7 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -822,7 +822,7 @@ static void shader_generate_arb_declarations(const struct wined3d_shader *shader if(use_nv_clip(gl_info) && ctx->target_version >= NV2) { if(ctx->cur_vs_args->super.clip_enabled) - clip_limit = gl_info->limits.clipplanes; + clip_limit = gl_info->limits.user_clip_distances; else clip_limit = 0; } @@ -835,13 +835,16 @@ static void shader_generate_arb_declarations(const struct wined3d_shader *shader max_constantsF -= *num_clipplanes; if(*num_clipplanes < clip_limit) { - WARN("Only %u clipplanes out of %u enabled\n", *num_clipplanes, gl_info->limits.clipplanes); + WARN("Only %u clip planes out of %u enabled.\n", *num_clipplanes, + gl_info->limits.user_clip_distances); } } else { - if (ctx->target_version >= NV2) *num_clipplanes = gl_info->limits.clipplanes; - else *num_clipplanes = min(gl_info->limits.clipplanes, 4); + if (ctx->target_version >= NV2) + *num_clipplanes = gl_info->limits.user_clip_distances; + else + *num_clipplanes = min(gl_info->limits.user_clip_distances, 4); } } @@ -3232,7 +3235,7 @@ static void vshader_add_footer(struct shader_arb_ctx_priv *priv_ctx, unsigned int cur_clip = 0; const char *zero = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_ZERO); - for (i = 0; i < gl_info->limits.clipplanes; ++i) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) { if (args->clip.boolclip.clipplane_mask & (1u << i)) { diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index de6d5a4..9bf6042 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1853,7 +1853,7 @@ HRESULT CDECL wined3d_device_set_clip_plane(struct wined3d_device *device, TRACE("device %p, plane_idx %u, plane %p.\n", device, plane_idx, plane); /* Validate plane_idx. */ - if (plane_idx >= device->adapter->gl_info.limits.clipplanes) + if (plane_idx >= device->adapter->gl_info.limits.user_clip_distances) { TRACE("Application has requested clipplane this device doesn't support.\n"); return WINED3DERR_INVALIDCALL; @@ -1882,7 +1882,7 @@ HRESULT CDECL wined3d_device_get_clip_plane(const struct wined3d_device *device, TRACE("device %p, plane_idx %u, plane %p.\n", device, plane_idx, plane); /* Validate plane_idx. */ - if (plane_idx >= device->adapter->gl_info.limits.clipplanes) + if (plane_idx >= device->adapter->gl_info.limits.user_clip_distances) { TRACE("Application has requested clipplane this device doesn't support.\n"); return WINED3DERR_INVALIDCALL; diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 6cd8535..5d324f3 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -3302,8 +3302,8 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) gl_info->limits.arb_ps_instructions = 0; gl_info->limits.arb_ps_temps = 0; - gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max); - gl_info->limits.clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max); + gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_CLIP_DISTANCES, &gl_max); + gl_info->limits.user_clip_distances = min(MAX_CLIP_DISTANCES, gl_max); TRACE("Clip plane support - max planes %d.\n", gl_max); gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_LIGHTS, &gl_max); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 4d9d9e7..9e9c83b 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1407,7 +1407,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context if (update_mask & WINED3D_SHADER_CONST_VS_CLIP_PLANES) { - for (i = 0; i < gl_info->limits.clipplanes; ++i) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) shader_glsl_clip_plane_uniform(context, state, i, prog); } @@ -1894,7 +1894,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont * clipplane as well. */ max_constantsF = gl_info->limits.glsl_vs_float_constants - 3; if (vs_args->clip_enabled) - max_constantsF -= gl_info->limits.clipplanes; + max_constantsF -= gl_info->limits.user_clip_distances; max_constantsF -= wined3d_popcount(reg_maps->integer_constants); /* Strictly speaking a bool only uses one scalar, but the nvidia(Linux) compiler doesn't pack them properly, * so each scalar requires a full vec4. We could work around this by packing the booleans ourselves, but @@ -2097,7 +2097,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) { if (vs_args->clip_enabled) - shader_addline(buffer, "uniform vec4 clip_planes[%u];\n", gl_info->limits.clipplanes); + shader_addline(buffer, "uniform vec4 clip_planes[%u];\n", gl_info->limits.user_clip_distances); if (version->major < 3) { @@ -6087,7 +6087,7 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context if (legacy_context) shader_addline(buffer, "gl_ClipVertex = gl_Position;\n"); else - for (i = 0; i < gl_info->limits.clipplanes; ++i) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) shader_addline(buffer, "gl_ClipDistance[%u] = dot(gl_Position, clip_planes[%u]);\n", i, i); } @@ -6625,7 +6625,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr else { if (settings->clipping) - shader_addline(buffer, "uniform vec4 clip_planes[%u];\n", gl_info->limits.clipplanes); + shader_addline(buffer, "uniform vec4 clip_planes[%u];\n", gl_info->limits.user_clip_distances); declare_out_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_diffuse;\n"); declare_out_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_specular;\n"); @@ -6674,7 +6674,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) shader_addline(buffer, "gl_ClipVertex = ec_pos;\n"); else - for (i = 0; i < gl_info->limits.clipplanes; ++i) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) shader_addline(buffer, "gl_ClipDistance[%u] = dot(ec_pos, clip_planes[%u]);\n", i, i); } shader_addline(buffer, "ec_pos /= ec_pos.w;\n"); @@ -8943,7 +8943,7 @@ static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, | WINED3DVTXPCAPS_LOCALVIEWER | WINED3DVTXPCAPS_TEXGEN_SPHEREMAP; caps->fvf_caps = WINED3DFVFCAPS_PSIZE | 8; /* 8 texture coordinates. */ - caps->max_user_clip_planes = gl_info->limits.clipplanes; + caps->max_user_clip_planes = gl_info->limits.user_clip_distances; caps->raster_caps = WINED3DPRASTERCAPS_FOGRANGE; } @@ -9032,7 +9032,7 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, if (context->last_was_vshader) { if (legacy_context) - for (i = 0; i < gl_info->limits.clipplanes; ++i) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) clipplane(context, state, STATE_CLIPPLANE(i)); else context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; @@ -9058,7 +9058,7 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, { /* Vertex shader clipping ignores the view matrix. Update all clip planes. */ if (legacy_context) - for (i = 0; i < gl_info->limits.clipplanes; ++i) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) clipplane(context, state, STATE_CLIPPLANE(i)); else context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; @@ -9119,7 +9119,7 @@ static void glsl_vertex_pipe_view(struct wined3d_context *context, const struct if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) { - for (k = 0; k < gl_info->limits.clipplanes; ++k) + for (k = 0; k < gl_info->limits.user_clip_distances; ++k) { if (!isStateDirty(context, STATE_CLIPPLANE(k))) clipplane(context, state, STATE_CLIPPLANE(k)); @@ -9229,7 +9229,7 @@ static void glsl_vertex_pipe_clip_plane(struct wined3d_context *context, const struct wined3d_gl_info *gl_info = context->gl_info; UINT index = state_id - STATE_CLIPPLANE(0); - if (index >= gl_info->limits.clipplanes) + if (index >= gl_info->limits.user_clip_distances) return; context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 9c1ddb0..d462ea5 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -609,7 +609,7 @@ void state_alpha_test(struct wined3d_context *context, const struct wined3d_stat void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int clipplane_count = gl_info->limits.clipplanes; + unsigned int clipplane_count = gl_info->limits.user_clip_distances; unsigned int i, enable_mask, disable_mask; if (use_vs(state) && !context->d3d_info->vs_clipping) @@ -3760,7 +3760,7 @@ void clipplane(struct wined3d_context *context, const struct wined3d_state *stat UINT index = state_id - STATE_CLIPPLANE(0); GLdouble plane[4]; - if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= gl_info->limits.clipplanes) + if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= gl_info->limits.user_clip_distances) return; gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW); @@ -3914,7 +3914,7 @@ static void transform_view(struct wined3d_context *context, const struct wined3d } /* Reset Clipping Planes */ - for (k = 0; k < gl_info->limits.clipplanes; ++k) + for (k = 0; k < gl_info->limits.user_clip_distances; ++k) { if (!isStateDirty(context, STATE_CLIPPLANE(k))) clipplane(context, state, STATE_CLIPPLANE(k)); @@ -4531,7 +4531,7 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)); } - for (i = 0; i < gl_info->limits.clipplanes; ++i) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) { clipplane(context, state, STATE_CLIPPLANE(i)); } @@ -4548,7 +4548,7 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine /* Disable all clip planes to get defined results on all drivers. See comment in the * state_clipping state handler */ - for (i = 0; i < gl_info->limits.clipplanes; ++i) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) { gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0 + i); checkGLcall("glDisable(GL_CLIP_PLANE0 + i)"); @@ -4580,7 +4580,7 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine * (Note: ARB shaders can read the clip planes for clipping emulation even if * device->vs_clipping is false. */ - for (i = 0; i < gl_info->limits.clipplanes; ++i) + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) { clipplane(context, state, STATE_CLIPPLANE(i)); } @@ -5699,7 +5699,7 @@ static void vp_ffp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3 | WINED3DVTXPCAPS_TEXGEN | WINED3DVTXPCAPS_TEXGEN_SPHEREMAP; caps->fvf_caps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */ - caps->max_user_clip_planes = gl_info->limits.clipplanes; + caps->max_user_clip_planes = gl_info->limits.user_clip_distances; caps->raster_caps = 0; if (gl_info->supported[NV_FOG_DISTANCE]) caps->raster_caps |= WINED3DPRASTERCAPS_FOGRANGE; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 45701cc..a9800b3 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -180,7 +180,7 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup #define MAX_VERTEX_SAMPLERS 4 #define MAX_COMBINED_SAMPLERS (MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS) #define MAX_ACTIVE_LIGHTS 8 -#define MAX_CLIPPLANES WINED3DMAXUSERCLIPPLANES +#define MAX_CLIP_DISTANCES WINED3DMAXUSERCLIPPLANES #define MAX_CONSTANT_BUFFERS 15 #define MAX_SAMPLER_OBJECTS 16 #define MAX_SHADER_RESOURCE_VIEWS 128 @@ -1333,9 +1333,9 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; #define STATE_IS_SCISSORRECT(a) ((a) == STATE_SCISSORRECT) #define STATE_CLIPPLANE(a) (STATE_SCISSORRECT + 1 + (a)) -#define STATE_IS_CLIPPLANE(a) ((a) >= STATE_CLIPPLANE(0) && (a) <= STATE_CLIPPLANE(MAX_CLIPPLANES - 1)) +#define STATE_IS_CLIPPLANE(a) ((a) >= STATE_CLIPPLANE(0) && (a) <= STATE_CLIPPLANE(MAX_CLIP_DISTANCES - 1)) -#define STATE_MATERIAL (STATE_CLIPPLANE(MAX_CLIPPLANES)) +#define STATE_MATERIAL (STATE_CLIPPLANE(MAX_CLIP_DISTANCES)) #define STATE_IS_MATERIAL(a) ((a) == STATE_MATERIAL) #define STATE_FRONTFACE (STATE_MATERIAL + 1) @@ -2057,7 +2057,7 @@ struct wined3d_gl_limits UINT vertex_samplers; UINT combined_samplers; UINT general_combiners; - UINT clipplanes; + UINT user_clip_distances; UINT texture_size; UINT texture3d_size; float pointsize_max; @@ -2396,7 +2396,7 @@ struct wined3d_state DWORD texture_states[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1]; struct wined3d_matrix transforms[HIGHEST_TRANSFORMSTATE + 1]; - struct wined3d_vec4 clip_planes[MAX_CLIPPLANES]; + struct wined3d_vec4 clip_planes[MAX_CLIP_DISTANCES]; struct wined3d_material material; struct wined3d_viewport viewport; RECT scissor_rect; -- 2.7.3 From aric at codeweavers.com Wed Oct 12 23:24:45 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 13 Oct 2016 06:24:45 +0200 Subject: include: Define IoSkipCurrentIrpStackLocation. (v3) In-Reply-To: <4beb7e60-2175-a6fb-512c-f2b9addc5d49@fds-team.de> References: <4beb7e60-2175-a6fb-512c-f2b9addc5d49@fds-team.de> Message-ID: <6f1d71d2-1b04-5cf6-a21c-b12160138522@codeweavers.com> Signed-off-by: Aric Stewart On 10/12/16 6:01 PM, Sebastian Lackner wrote: > From: Aric Stewart > > Signed-off-by: Aric Stewart > Signed-off-by: Sebastian Lackner > --- > > Changes in v3: > * Remove unnecessary (). > > include/ddk/wdm.h | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h > index 5602f7d..74251fc 100644 > --- a/include/ddk/wdm.h > +++ b/include/ddk/wdm.h > @@ -1175,17 +1175,21 @@ NTSTATUS WINAPI ObCloseHandle(IN HANDLE handle); > # ifdef NONAMELESSSTRUCT > # define IoGetCurrentIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.s.u2.CurrentStackLocation) > # define IoGetNextIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.s.u2.CurrentStackLocation - 1) > +# define IoSkipCurrentIrpStackLocation(_Irp) {(_Irp)->Tail.Overlay.s.u2.CurrentStackLocation++; (_Irp)->CurrentLocation++;} > # else > # define IoGetCurrentIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.u2.CurrentStackLocation) > # define IoGetNextIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.u2.CurrentStackLocation - 1) > +# define IoSkipCurrentIrpStackLocation(_Irp) {(_Irp)->Tail.Overlay.u2.CurrentStackLocation++; (_Irp)->CurrentLocation++;} > # endif > #else > # ifdef NONAMELESSSTRUCT > # define IoGetCurrentIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.s.CurrentStackLocation) > # define IoGetNextIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.s.CurrentStackLocation - 1) > +# define IoSkipCurrentIrpStackLocation(_Irp) {(_Irp)->Tail.Overlay.s.CurrentStackLocation++; (_Irp)->CurrentLocation++;} > # else > # define IoGetCurrentIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.CurrentStackLocation) > # define IoGetNextIrpStackLocation(_Irp) ((_Irp)->Tail.Overlay.CurrentStackLocation - 1) > +# define IoSkipCurrentIrpStackLocation(_Irp) {(_Irp)->Tail.Overlay.CurrentStackLocation++; (_Irp)->CurrentLocation++;} > # endif > #endif > > From aric at codeweavers.com Wed Oct 12 23:25:39 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 13 Oct 2016 06:25:39 +0200 Subject: [1/2] winehid.sys: Add HID minidriver. (v2) In-Reply-To: <631aa9ff-ee35-e66b-a0d7-00c59138d35a@fds-team.de> References: <631aa9ff-ee35-e66b-a0d7-00c59138d35a@fds-team.de> Message-ID: <35a9e07f-6efb-b83b-aeff-989a5b7ff39b@codeweavers.com> Signed-off-by: Aric Stewart On 10/12/16 5:46 PM, Sebastian Lackner wrote: > From: Aric Stewart > > Signed-off-by: Aric Stewart > Signed-off-by: Sebastian Lackner > --- > > Changes in v2: > * Avoid unnecessary ntoskrnl import. > * Remove unnecessary NONAMELESSUNION define. > * Change debug channel to "hid". I don't think we really need > a separate one just for two or three functions related to HID handling. > * Actually TRACE both arguments passed to DriverEntry. > * Return STATUS_SUCCESS (otherwise the driver fails loading). > * Rename service name "WineHIDMinidriver" -> "WineHID". > > MAINTAINERS | 1 + > configure.ac | 1 + > dlls/winehid.sys/Makefile.in | 5 +++++ > dlls/winehid.sys/main.c | 38 ++++++++++++++++++++++++++++++++++++++ > dlls/winehid.sys/winehid.sys.spec | 1 + > loader/wine.inf.in | 14 ++++++++++++++ > 6 files changed, 60 insertions(+) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 4a7191c..55a7834 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -122,6 +122,7 @@ HID support > M: Aric Stewart > F: dlls/hid/ > F: dlls/hidclass.sys/ > +F: dlls/winehid.sys/ > > HTML rendering (Gecko) > M: Jacek Caban > diff --git a/configure.ac b/configure.ac > index 78c5a02..964c593 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -3425,6 +3425,7 @@ WINE_CONFIG_DLL(winecoreaudio.drv) > WINE_CONFIG_LIB(winecrt0) > WINE_CONFIG_DLL(wined3d,,[implib]) > WINE_CONFIG_DLL(winegstreamer) > +WINE_CONFIG_DLL(winehid.sys) > WINE_CONFIG_DLL(winejoystick.drv) > WINE_CONFIG_DLL(winemac.drv,,[clean]) > WINE_CONFIG_DLL(winemapi) > diff --git a/dlls/winehid.sys/Makefile.in b/dlls/winehid.sys/Makefile.in > new file mode 100644 > index 0000000..d4ca3dd > --- /dev/null > +++ b/dlls/winehid.sys/Makefile.in > @@ -0,0 +1,5 @@ > +MODULE = winehid.sys > +EXTRADLLFLAGS = -Wb,--subsystem,native > + > +C_SRCS = \ > + main.c > diff --git a/dlls/winehid.sys/main.c b/dlls/winehid.sys/main.c > new file mode 100644 > index 0000000..7ab9267 > --- /dev/null > +++ b/dlls/winehid.sys/main.c > @@ -0,0 +1,38 @@ > +/* > + * WINE Hid minidriver > + * > + * Copyright 2016 Aric Stewart > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA > + */ > + > +#include > + > +#include "ntstatus.h" > +#define WIN32_NO_STATUS > +#include "windef.h" > +#include "winbase.h" > +#include "winternl.h" > +#include "ddk/wdm.h" > +#include "wine/debug.h" > + > +WINE_DEFAULT_DEBUG_CHANNEL(hid); > + > +NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path) > +{ > + TRACE("(%p, %s)\n", driver, debugstr_w(path->Buffer)); > + > + return STATUS_SUCCESS; > +} > diff --git a/dlls/winehid.sys/winehid.sys.spec b/dlls/winehid.sys/winehid.sys.spec > new file mode 100644 > index 0000000..76421d7 > --- /dev/null > +++ b/dlls/winehid.sys/winehid.sys.spec > @@ -0,0 +1 @@ > +# nothing to export > diff --git a/loader/wine.inf.in b/loader/wine.inf.in > index a92a9fe..fcf9c4a 100644 > --- a/loader/wine.inf.in > +++ b/loader/wine.inf.in > @@ -131,6 +131,7 @@ AddService=LanmanServer,0,LanmanServerService > AddService=FontCache,0,FontCacheService > AddService=Schedule,0,TaskSchedulerService > AddService=WineBus,0,WineBusService > +AddService=WineHID,0,WineHIDService > > [DefaultInstall.NT.Services] > AddService=BITS,0,BITSService > @@ -146,6 +147,7 @@ AddService=LanmanServer,0,LanmanServerService > AddService=FontCache,0,FontCacheService > AddService=Schedule,0,TaskSchedulerService > AddService=WineBus,0,WineBusService > +AddService=WineHID,0,WineHIDService > > [DefaultInstall.ntamd64.Services] > AddService=BITS,0,BITSService > @@ -161,6 +163,7 @@ AddService=LanmanServer,0,LanmanServerService > AddService=FontCache,0,FontCacheService > AddService=Schedule,0,TaskSchedulerService > AddService=WineBus,0,WineBusService > +AddService=WineHID,0,WineHIDService > > [Strings] > MciExtStr="Software\Microsoft\Windows NT\CurrentVersion\MCI Extensions" > @@ -2530,6 +2533,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" > 12,,ndis.sys,- > 12,,tdi.sys,- > 12,,winebus.sys,- > +12,,winehid.sys,- > ; skip .NET fake dlls in Wine Mono package > 11,,aspnet_regiis.exe,- > 11,,ngen.exe,- > @@ -2573,6 +2577,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" > 12,,ndis.sys > 12,,tdi.sys > 12,,winebus.sys > +12,,winehid.sys > ; skip .NET fake dlls in Wine Mono package > 11,,aspnet_regiis.exe,- > 11,,ngen.exe,- > @@ -3198,6 +3203,15 @@ ServiceType=1 > StartType=3 > ErrorControl=1 > > +[WineHIDService] > +Description="Wine HID Minidriver" > +DisplayName="Wine HID" > +ServiceBinary="%12%\winehid.sys" > +LoadOrderGroup="WinePlugPlay" > +ServiceType=1 > +StartType=3 > +ErrorControl=1 > + > [SpoolerService] > Description="Loads files to memory for later printing" > DisplayName="Print Spooler" > From aric at codeweavers.com Wed Oct 12 23:26:44 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 13 Oct 2016 06:26:44 +0200 Subject: [2/2] winehid.sys: Register as a HID minidriver. (v2) In-Reply-To: <02d24bf4-604a-7b9f-0ef5-04d48a0693fc@fds-team.de> References: <02d24bf4-604a-7b9f-0ef5-04d48a0693fc@fds-team.de> Message-ID: Signed-off-by: Aric Stewart On 10/12/16 5:46 PM, Sebastian Lackner wrote: > From: Aric Stewart > > Signed-off-by: Aric Stewart > Signed-off-by: Sebastian Lackner > --- > > Changes in v2: > * TRACE arguments of add_device. > * Declare HID_MINIDRIVER_REGISTRATION directly in DriverEntry (it does > not seem to be used anywhere else, so why static?) > * Pass through NTSTATUS from HidRegisterMinidriver. > > dlls/winehid.sys/Makefile.in | 1 + > dlls/winehid.sys/main.c | 19 ++++++++++++++++++- > 2 files changed, 19 insertions(+), 1 deletion(-) > > diff --git a/dlls/winehid.sys/Makefile.in b/dlls/winehid.sys/Makefile.in > index d4ca3dd..ad7881e 100644 > --- a/dlls/winehid.sys/Makefile.in > +++ b/dlls/winehid.sys/Makefile.in > @@ -1,4 +1,5 @@ > MODULE = winehid.sys > +IMPORTS = hidclass > EXTRADLLFLAGS = -Wb,--subsystem,native > > C_SRCS = \ > diff --git a/dlls/winehid.sys/main.c b/dlls/winehid.sys/main.c > index 7ab9267..cdef3c5 100644 > --- a/dlls/winehid.sys/main.c > +++ b/dlls/winehid.sys/main.c > @@ -26,13 +26,30 @@ > #include "winbase.h" > #include "winternl.h" > #include "ddk/wdm.h" > +#include "ddk/hidport.h" > #include "wine/debug.h" > > WINE_DEFAULT_DEBUG_CHANNEL(hid); > > +static NTSTATUS WINAPI add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *device) > +{ > + TRACE("(%p, %p)\n", driver, device); > + return STATUS_SUCCESS; > +} > + > NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path) > { > + HID_MINIDRIVER_REGISTRATION registration; > + > TRACE("(%p, %s)\n", driver, debugstr_w(path->Buffer)); > > - return STATUS_SUCCESS; > + driver->DriverExtension->AddDevice = add_device; > + > + memset(®istration, 0, sizeof(registration)); > + registration.DriverObject = driver; > + registration.RegistryPath = path; > + registration.DeviceExtensionSize = sizeof(HID_DEVICE_EXTENSION); > + registration.DevicesArePolled = FALSE; > + > + return HidRegisterMinidriver(®istration); > } > From aurimas at members.fsf.org Thu Oct 13 00:23:58 2016 From: aurimas at members.fsf.org (=?UTF-8?Q?Aurimas_Fi=c5=a1eras?=) Date: Thu, 13 Oct 2016 08:23:58 +0300 Subject: po: Update Lithuanian translation Message-ID: <57FF1A6E.3060805@members.fsf.org> A non-text attachment was scrubbed... Name: 0001-po-Update-Lithuanian-translation.patch Type: text/x-patch Size: 1772 bytes Desc: not available URL: From leslie_alistair at hotmail.com Thu Oct 13 05:07:08 2016 From: leslie_alistair at hotmail.com (Alistair Leslie-Hughes) Date: Thu, 13 Oct 2016 10:07:08 +0000 Subject: [PATCH] dpnet: Correct GetComponentByName to return the correct buffer size Message-ID: Signed-off-by: Alistair Leslie-Hughes --- dlls/dpnet/address.c | 4 ++-- dlls/dpnet/tests/address.c | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/dlls/dpnet/address.c b/dlls/dpnet/address.c index d87d4e7..6305fe7 100644 --- a/dlls/dpnet/address.c +++ b/dlls/dpnet/address.c @@ -377,9 +377,9 @@ static HRESULT WINAPI IDirectPlay8AddressImpl_GetComponentByName(IDirectPlay8Add struct component *entry; DWORD i; - TRACE("(%p)->(%p %p %p %p)\n", This, pwszName, pvBuffer, pdwBufferSize, pdwDataType); + TRACE("(%p)->(%s %p %p %p)\n", This, debugstr_w(pwszName), pvBuffer, pdwBufferSize, pdwDataType); - if(!pwszName || !pdwBufferSize || !pdwDataType || (!pvBuffer && pdwBufferSize)) + if(!pwszName || !pdwBufferSize || !pdwDataType || (!pvBuffer && *pdwBufferSize)) return E_POINTER; for(i=0; i < This->comp_count; i++) diff --git a/dlls/dpnet/tests/address.c b/dlls/dpnet/tests/address.c index cb226f9..dd0ef23 100644 --- a/dlls/dpnet/tests/address.c +++ b/dlls/dpnet/tests/address.c @@ -123,6 +123,15 @@ static void address_addcomponents(void) hr = IDirectPlay8Address_AddComponent(localaddr, DPNA_KEY_HOSTNAME, &localhost, sizeof(localhost)+2, DPNA_DATATYPE_STRING); ok(hr == DPNERR_INVALIDPARAM, "got 0x%08x\n", hr); + size = 0; + hr = IDirectPlay8Address_GetComponentByName(localaddr, DPNA_KEY_HOSTNAME, NULL, &size, &type); + ok(hr == DPNERR_BUFFERTOOSMALL, "got 0x%08x\n", hr); + ok(size == sizeof(localhost), "Invalid string length: %d\n", size); + + size = 1; + hr = IDirectPlay8Address_GetComponentByName(localaddr, DPNA_KEY_HOSTNAME, NULL, &size, &type); + ok(hr == E_POINTER, "got 0x%08x\n", hr); + size = sizeof(buffer); hr = IDirectPlay8Address_GetComponentByName(localaddr, DPNA_KEY_HOSTNAME, buffer, &size, &type); ok(hr == S_OK, "got 0x%08x\n", hr); -- 2.9.3 From aric at codeweavers.com Thu Oct 13 06:49:35 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 13 Oct 2016 13:49:35 +0200 Subject: [PATCH v3 3/3] include: Define IoSkipCurrentIrpStackLocation Message-ID: <3a687c5c-2399-9aec-6e4d-32a7a78af900@codeweavers.com> v2: Suggestions from Sebastian Lackner v3: use static inline as suggested by Alexandre Julliard Signed-off-by: Aric Stewart --- include/ddk/wdm.h | 4 ++++ 1 file changed, 4 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: v3-0003-include-Define-IoSkipCurrentIrpStackLocation.txt Type: text/x-patch Size: 1586 bytes Desc: not available URL: From hverbeet at codeweavers.com Thu Oct 13 08:25:18 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Thu, 13 Oct 2016 15:25:18 +0200 Subject: [PATCH 1/5] d3d11/tests: Make the window client rect match the d3d swapchain size. In-Reply-To: <1476313450-31082-1-git-send-email-mbruni@codeweavers.com> References: <1476313450-31082-1-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Thu Oct 13 08:25:19 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Thu, 13 Oct 2016 15:25:19 +0200 Subject: [PATCH 2/5] d3d11/tests: Add a test for derivative shader instructions. In-Reply-To: <1476313450-31082-2-git-send-email-mbruni@codeweavers.com> References: <1476313450-31082-2-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Thu Oct 13 08:25:20 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Thu, 13 Oct 2016 15:25:20 +0200 Subject: [PATCH 3/5] d3d10core/tests: Make the window client rect match the d3d swapchain size. In-Reply-To: <1476313450-31082-3-git-send-email-mbruni@codeweavers.com> References: <1476313450-31082-3-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Thu Oct 13 08:25:22 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Thu, 13 Oct 2016 15:25:22 +0200 Subject: [PATCH 5/5] wined3d: Cleanup user clip distances defines and fields a bit. In-Reply-To: <1476313450-31082-5-git-send-email-mbruni@codeweavers.com> References: <1476313450-31082-5-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Thu Oct 13 08:25:21 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Thu, 13 Oct 2016 15:25:21 +0200 Subject: [PATCH 4/5] d3d10core/tests: Add a test for ddy. In-Reply-To: <1476313450-31082-4-git-send-email-mbruni@codeweavers.com> References: <1476313450-31082-4-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From sebastian at fds-team.de Thu Oct 13 08:39:50 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Thu, 13 Oct 2016 15:39:50 +0200 Subject: [PATCH v3 3/3] include: Define IoSkipCurrentIrpStackLocation In-Reply-To: <3a687c5c-2399-9aec-6e4d-32a7a78af900@codeweavers.com> References: <3a687c5c-2399-9aec-6e4d-32a7a78af900@codeweavers.com> Message-ID: <2836490d-b78a-4c9f-a463-1cc94c2d0426@fds-team.de> On 13.10.2016 13:49, Aric Stewart wrote: > v2: Suggestions from Sebastian Lackner > v3: use static inline as suggested by Alexandre Julliard > Signed-off-by: Aric Stewart > --- > include/ddk/wdm.h | 4 ++++ > 1 file changed, 4 insertions(+) Signed-off-by: Sebastian Lackner From huw at codeweavers.com Thu Oct 13 10:20:03 2016 From: huw at codeweavers.com (Huw Davies) Date: Thu, 13 Oct 2016 16:20:03 +0100 Subject: [PATCH 1/2] riched20/tests: Add a test to show the insert style is cleared if the selection changes. Message-ID: <1476372004-5605-1-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/tests/editor.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index d694d28..88270aa 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -1057,6 +1057,14 @@ static void test_EM_SETCHARFORMAT(void) /* Set two effects on an empty selection */ SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine"); + /* first clear bold, italic */ + SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + cf2.dwMask = CFM_BOLD | CFM_ITALIC; + cf2.dwEffects = 0; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + SendMessageA(hwndRichEdit, EM_SETSEL, 2, 2); /* Empty selection */ memset(&cf2, 0, sizeof(CHARFORMAT2A)); @@ -1084,6 +1092,14 @@ static void test_EM_SETCHARFORMAT(void) /* Setting the (empty) selection to exactly the same place as before should NOT clear the insertion style! */ SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine"); + /* first clear bold, italic */ + SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + cf2.dwMask = CFM_BOLD | CFM_ITALIC; + cf2.dwEffects = 0; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + SendMessageA(hwndRichEdit, EM_SETSEL, 2, 2); /* Empty selection */ memset(&cf2, 0, sizeof(CHARFORMAT2A)); @@ -1108,8 +1124,51 @@ static void test_EM_SETCHARFORMAT(void) ok((cf2.dwEffects & CFE_BOLD) == CFE_BOLD, "%d, cf2.dwEffects == 0x%08x expected effect 0x%08x\n", i, cf2.dwEffects, CFE_BOLD); + /* Moving the selection will clear the insertion style */ + SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine"); + /* first clear bold, italic */ + SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + cf2.dwMask = CFM_BOLD | CFM_ITALIC; + cf2.dwEffects = 0; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + + SendMessageA(hwndRichEdit, EM_SETSEL, 2, 2); /* Empty selection */ + + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + cf2.dwMask = CFM_BOLD; + cf2.dwEffects = CFE_BOLD; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + + /* Move selection and then put it back, insert style should be forgotten here. */ + SendMessageA(hwndRichEdit, EM_SETSEL, 3, 3); + SendMessageA(hwndRichEdit, EM_SETSEL, 2, 2); /* Empty selection */ + + /* Selection is now nonempty */ + SendMessageA(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)"newi"); + + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + SendMessageA(hwndRichEdit, EM_SETSEL, 2, 6); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + + ok(((cf2.dwMask & CFM_BOLD) == CFM_BOLD), + "%d, cf2.dwMask == 0x%08x expected mask 0x%08x\n", i, cf2.dwMask, CFM_BOLD); + ok((cf2.dwEffects & CFE_BOLD) == 0, + "%d, cf2.dwEffects == 0x%08x not expecting effect 0x%08x\n", i, cf2.dwEffects, CFE_BOLD); + /* Ditto with EM_EXSETSEL */ SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine"); + /* first clear bold, italic */ + SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + cf2.dwMask = CFM_BOLD | CFM_ITALIC; + cf2.dwEffects = 0; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + cr.cpMin = 2; cr.cpMax = 2; SendMessageA(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM)&cr); /* Empty selection */ -- 2.8.2 From huw at codeweavers.com Thu Oct 13 10:20:04 2016 From: huw at codeweavers.com (Huw Davies) Date: Thu, 13 Oct 2016 16:20:04 +0100 Subject: [PATCH 2/2] include: Add a padding WORD to ensure that wWeight is at the correct offset. Message-ID: <1476372004-5605-2-git-send-email-huw@codeweavers.com> This is a bug in MS's C version of these structures. Signed-off-by: Huw Davies --- dlls/riched20/tests/editor.c | 39 +++++++++++++++++++++++++++++++++++++++ include/richedit.h | 2 ++ 2 files changed, 41 insertions(+) diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 88270aa..194ff45 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -747,6 +747,7 @@ static void test_EM_SETCHARFORMAT(void) { HWND hwndRichEdit = new_richedit(NULL); CHARFORMAT2A cf2; + CHARFORMAT2W cfW; int rc = 0; int tested_effects[] = { CFE_BOLD, @@ -1196,6 +1197,44 @@ static void test_EM_SETCHARFORMAT(void) ok((cf2.dwEffects & CFE_BOLD) == CFE_BOLD, "%d, cf2.dwEffects == 0x%08x expected effect 0x%08x\n", i, cf2.dwEffects, CFE_BOLD); + /* show that wWeight is at the correct offset in CHARFORMAT2A */ + memset(&cf2, 0, sizeof(cf2)); + cf2.dwMask = CFM_WEIGHT; + cf2.wWeight = 100; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + memset(&cf2, 0, sizeof(cf2)); + cf2.cbSize = sizeof(cf2); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + ok(cf2.wWeight == 100, "got %d\n", cf2.wWeight); + + memset(&cf2, 0, sizeof(cf2)); + cf2.dwMask = CFM_SPACING; + cf2.sSpacing = 10; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + memset(&cf2, 0, sizeof(cf2)); + cf2.cbSize = sizeof(cf2); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + ok(cf2.sSpacing == 10, "got %d\n", cf2.sSpacing); + + /* show that wWeight is at the correct offset in CHARFORMAT2W */ + memset(&cfW, 0, sizeof(cfW)); + cfW.dwMask = CFM_WEIGHT; + cfW.wWeight = 100; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cfW); + memset(&cfW, 0, sizeof(cfW)); + cfW.cbSize = sizeof(cfW); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cfW); + ok(cfW.wWeight == 100, "got %d\n", cfW.wWeight); + + memset(&cfW, 0, sizeof(cfW)); + cfW.dwMask = CFM_SPACING; + cfW.sSpacing = 10; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cfW); + memset(&cfW, 0, sizeof(cfW)); + cfW.cbSize = sizeof(cfW); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cfW); + ok(cfW.sSpacing == 10, "got %d\n", cfW.sSpacing); + DestroyWindow(hwndRichEdit); } diff --git a/include/richedit.h b/include/richedit.h index f0ae57e..63221e2 100644 --- a/include/richedit.h +++ b/include/richedit.h @@ -287,6 +287,7 @@ typedef struct _charformat2a { BYTE bCharSet; BYTE bPitchAndFamily; char szFaceName[LF_FACESIZE]; + WORD pad; /* Not in MS's C version, but needed to ensure that wWeight is at the correct offset to match the C++ version */ WORD wWeight; SHORT sSpacing; COLORREF crBackColor; @@ -309,6 +310,7 @@ typedef struct _charformat2w { BYTE bCharSet; BYTE bPitchAndFamily; WCHAR szFaceName[LF_FACESIZE]; + WORD pad; /* Not in MS's C version, but needed to ensure that wWeight is at the correct offset to match the C++ version */ WORD wWeight; SHORT sSpacing; COLORREF crBackColor; -- 2.8.2 From huw at codeweavers.com Thu Oct 13 10:52:48 2016 From: huw at codeweavers.com (Huw Davies) Date: Thu, 13 Oct 2016 16:52:48 +0100 Subject: [PATCH v2 1/2] riched20/tests: Add a test to show the insert style is cleared if the selection changes. Message-ID: <1476373969-6286-1-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/tests/editor.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index d694d28..88270aa 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -1057,6 +1057,14 @@ static void test_EM_SETCHARFORMAT(void) /* Set two effects on an empty selection */ SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine"); + /* first clear bold, italic */ + SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + cf2.dwMask = CFM_BOLD | CFM_ITALIC; + cf2.dwEffects = 0; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + SendMessageA(hwndRichEdit, EM_SETSEL, 2, 2); /* Empty selection */ memset(&cf2, 0, sizeof(CHARFORMAT2A)); @@ -1084,6 +1092,14 @@ static void test_EM_SETCHARFORMAT(void) /* Setting the (empty) selection to exactly the same place as before should NOT clear the insertion style! */ SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine"); + /* first clear bold, italic */ + SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + cf2.dwMask = CFM_BOLD | CFM_ITALIC; + cf2.dwEffects = 0; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + SendMessageA(hwndRichEdit, EM_SETSEL, 2, 2); /* Empty selection */ memset(&cf2, 0, sizeof(CHARFORMAT2A)); @@ -1108,8 +1124,51 @@ static void test_EM_SETCHARFORMAT(void) ok((cf2.dwEffects & CFE_BOLD) == CFE_BOLD, "%d, cf2.dwEffects == 0x%08x expected effect 0x%08x\n", i, cf2.dwEffects, CFE_BOLD); + /* Moving the selection will clear the insertion style */ + SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine"); + /* first clear bold, italic */ + SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + cf2.dwMask = CFM_BOLD | CFM_ITALIC; + cf2.dwEffects = 0; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + + SendMessageA(hwndRichEdit, EM_SETSEL, 2, 2); /* Empty selection */ + + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + cf2.dwMask = CFM_BOLD; + cf2.dwEffects = CFE_BOLD; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + + /* Move selection and then put it back, insert style should be forgotten here. */ + SendMessageA(hwndRichEdit, EM_SETSEL, 3, 3); + SendMessageA(hwndRichEdit, EM_SETSEL, 2, 2); /* Empty selection */ + + /* Selection is now nonempty */ + SendMessageA(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)"newi"); + + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + SendMessageA(hwndRichEdit, EM_SETSEL, 2, 6); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + + ok(((cf2.dwMask & CFM_BOLD) == CFM_BOLD), + "%d, cf2.dwMask == 0x%08x expected mask 0x%08x\n", i, cf2.dwMask, CFM_BOLD); + ok((cf2.dwEffects & CFE_BOLD) == 0, + "%d, cf2.dwEffects == 0x%08x not expecting effect 0x%08x\n", i, cf2.dwEffects, CFE_BOLD); + /* Ditto with EM_EXSETSEL */ SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine"); + /* first clear bold, italic */ + SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + cf2.dwMask = CFM_BOLD | CFM_ITALIC; + cf2.dwEffects = 0; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + cr.cpMin = 2; cr.cpMax = 2; SendMessageA(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM)&cr); /* Empty selection */ -- 2.8.2 From huw at codeweavers.com Thu Oct 13 10:52:49 2016 From: huw at codeweavers.com (Huw Davies) Date: Thu, 13 Oct 2016 16:52:49 +0100 Subject: [PATCH v2 2/2] include: Add a padding WORD to ensure that wWeight is at the correct offset. Message-ID: <1476373969-6286-2-git-send-email-huw@codeweavers.com> This is a bug in MS's C version of these structures. Signed-off-by: Huw Davies --- dlls/riched20/tests/editor.c | 43 +++++++++++++++++++++++++++++++++++++++++++ include/richedit.h | 2 ++ 2 files changed, 45 insertions(+) diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 88270aa..36e082e 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -747,6 +747,7 @@ static void test_EM_SETCHARFORMAT(void) { HWND hwndRichEdit = new_richedit(NULL); CHARFORMAT2A cf2; + CHARFORMAT2W cfW; int rc = 0; int tested_effects[] = { CFE_BOLD, @@ -1196,6 +1197,48 @@ static void test_EM_SETCHARFORMAT(void) ok((cf2.dwEffects & CFE_BOLD) == CFE_BOLD, "%d, cf2.dwEffects == 0x%08x expected effect 0x%08x\n", i, cf2.dwEffects, CFE_BOLD); + /* show that wWeight is at the correct offset in CHARFORMAT2A */ + memset(&cf2, 0, sizeof(cf2)); + cf2.cbSize = sizeof(cf2); + cf2.dwMask = CFM_WEIGHT; + cf2.wWeight = 100; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + memset(&cf2, 0, sizeof(cf2)); + cf2.cbSize = sizeof(cf2); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + ok(cf2.wWeight == 100, "got %d\n", cf2.wWeight); + + memset(&cf2, 0, sizeof(cf2)); + cf2.cbSize = sizeof(cf2); + cf2.dwMask = CFM_SPACING; + cf2.sSpacing = 10; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + memset(&cf2, 0, sizeof(cf2)); + cf2.cbSize = sizeof(cf2); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + ok(cf2.sSpacing == 10, "got %d\n", cf2.sSpacing); + + /* show that wWeight is at the correct offset in CHARFORMAT2W */ + memset(&cfW, 0, sizeof(cfW)); + cfW.cbSize = sizeof(cfW); + cfW.dwMask = CFM_WEIGHT; + cfW.wWeight = 100; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cfW); + memset(&cfW, 0, sizeof(cfW)); + cfW.cbSize = sizeof(cfW); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cfW); + ok(cfW.wWeight == 100, "got %d\n", cfW.wWeight); + + memset(&cfW, 0, sizeof(cfW)); + cfW.cbSize = sizeof(cfW); + cfW.dwMask = CFM_SPACING; + cfW.sSpacing = 10; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cfW); + memset(&cfW, 0, sizeof(cfW)); + cfW.cbSize = sizeof(cfW); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cfW); + ok(cfW.sSpacing == 10, "got %d\n", cfW.sSpacing); + DestroyWindow(hwndRichEdit); } diff --git a/include/richedit.h b/include/richedit.h index f0ae57e..63221e2 100644 --- a/include/richedit.h +++ b/include/richedit.h @@ -287,6 +287,7 @@ typedef struct _charformat2a { BYTE bCharSet; BYTE bPitchAndFamily; char szFaceName[LF_FACESIZE]; + WORD pad; /* Not in MS's C version, but needed to ensure that wWeight is at the correct offset to match the C++ version */ WORD wWeight; SHORT sSpacing; COLORREF crBackColor; @@ -309,6 +310,7 @@ typedef struct _charformat2w { BYTE bCharSet; BYTE bPitchAndFamily; WCHAR szFaceName[LF_FACESIZE]; + WORD pad; /* Not in MS's C version, but needed to ensure that wWeight is at the correct offset to match the C++ version */ WORD wWeight; SHORT sSpacing; COLORREF crBackColor; -- 2.8.2 From madewokherd at gmail.com Thu Oct 13 13:26:43 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Thu, 13 Oct 2016 13:26:43 -0500 Subject: [1/3] gdiplus/tests: Add tests for 0-pixel pens. Message-ID: <1476383205-7103-1-git-send-email-madewokherd@gmail.com> From: Vincent Povirk Signed-off-by: Vincent Povirk --- dlls/gdiplus/tests/graphics.c | 1 + dlls/gdiplus/tests/graphicspath.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c index d86f49d..851671b 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -3903,6 +3903,7 @@ static void test_pen_thickness(void) } td[] = { { 10.0, 10.0, 1.0, UnitPixel, UnitPixel, 1.0, 1, 1 }, + { 10.0, 10.0, 1.0, UnitPixel, UnitPixel, 0.0, 1, 1 }, { 10.0, 10.0, 3.0, UnitPixel, UnitPixel, 2.0, 2, 2 }, { 10.0, 10.0, 30.0, UnitPixel, UnitInch, 1.0, 1, 1 }, { 10.0, 10.0, 1.0, UnitWorld, UnitPixel, 1.0, 1, 1 }, diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index c43fb42..c44ed5e 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -1071,6 +1071,7 @@ static void test_widen(void) GpPath *path; GpPen *pen; GpMatrix *m; + INT count=-1; status = GdipCreatePath(FillModeAlternate, &path); expect(Ok, status); @@ -1195,6 +1196,23 @@ static void test_widen(void) expect(Ok, status); ok_path(path, widenline_path, sizeof(widenline_path)/sizeof(path_test_t), FALSE); + /* pen width = 0 pixels - native fails to widen but can draw with this pen */ + GdipDeletePen(pen); + status = GdipCreatePen1(0xffffffff, 0.0, UnitPixel, &pen); + expect(Ok, status); + + status = GdipResetPath(path); + expect(Ok, status); + status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0); + expect(Ok, status); + + status = GdipWidenPath(path, pen, m, 1.0); + expect(Ok, status); + + status = GdipGetPointCount(path, &count); + expect(Ok, status); + todo_wine expect(0, count); + GdipDeleteMatrix(m); GdipDeletePen(pen); GdipDeletePath(path); -- 2.7.4 From madewokherd at gmail.com Thu Oct 13 13:26:44 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Thu, 13 Oct 2016 13:26:44 -0500 Subject: [2/3] gdiplus: Add non-gdi32 implementation of GdipDrawPath. Message-ID: <1476383205-7103-2-git-send-email-madewokherd@gmail.com> From: Vincent Povirk Signed-off-by: Vincent Povirk --- dlls/gdiplus/graphics.c | 84 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 15 deletions(-) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 076ed81..66a9f97 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -3369,26 +3369,12 @@ GpStatus WINGDIPAPI GdipDrawLinesI(GpGraphics *graphics, GpPen *pen, GDIPCONST return retval; } -GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) +GpStatus GDI32_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) { INT save_state; GpStatus retval; HRGN hrgn=NULL; - TRACE("(%p, %p, %p)\n", graphics, pen, path); - - if(!pen || !graphics) - return InvalidParameter; - - if(graphics->busy) - return ObjectBusy; - - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } - save_state = prepare_dc(graphics, pen); retval = get_clip_hrgn(graphics, &hrgn); @@ -3409,6 +3395,74 @@ end: return retval; } +GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) +{ + GpStatus stat; + GpPath *wide_path; + GpMatrix *transform=NULL; + + stat = GdipClonePath(path, &wide_path); + + if (stat != Ok) + return stat; + + if (pen->unit == UnitPixel) + { + /* We have to transform this to device coordinates to get the widths right. */ + stat = GdipCreateMatrix(&transform); + + if (stat == Ok) + stat = get_graphics_transform(graphics, CoordinateSpaceDevice, + CoordinateSpaceWorld, transform); + } + + if (stat == Ok) + stat = GdipWidenPath(wide_path, pen, transform, 1.0); + + if (pen->unit == UnitPixel) + { + /* Transform the path back to world coordinates */ + if (stat == Ok) + stat = GdipInvertMatrix(transform); + + if (stat == Ok) + stat = GdipTransformPath(wide_path, transform); + } + + /* Actually draw the path */ + if (stat == Ok) + stat = GdipFillPath(graphics, pen->brush, wide_path); + + GdipDeleteMatrix(transform); + + GdipDeletePath(wide_path); + + return stat; +} + +GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) +{ + GpStatus retval; + + TRACE("(%p, %p, %p)\n", graphics, pen, path); + + if(!pen || !graphics) + return InvalidParameter; + + if(graphics->busy) + return ObjectBusy; + + if (path->pathdata.Count == 0) + return Ok; + + if (!graphics->hdc) + retval = SOFTWARE_GdipDrawPath(graphics, pen, path); + else + retval = GDI32_GdipDrawPath(graphics, pen, path); + + return retval; +} + GpStatus WINGDIPAPI GdipDrawPie(GpGraphics *graphics, GpPen *pen, REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle) { -- 2.7.4 From madewokherd at gmail.com Thu Oct 13 13:26:45 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Thu, 13 Oct 2016 13:26:45 -0500 Subject: [3/3] gdiplus: Add a software path for thin line drawing. Message-ID: <1476383205-7103-3-git-send-email-madewokherd@gmail.com> From: Vincent Povirk Signed-off-by: Vincent Povirk --- dlls/gdiplus/graphics.c | 324 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 66a9f97..f7817e5 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -3395,12 +3395,336 @@ end: return retval; } +GpStatus SOFTWARE_GdipDrawThinPath(GpGraphics *graphics, GpPen *pen, GpPath *path) +{ + GpStatus stat; + GpPath* flat_path; + GpMatrix* transform; + GpRectF gp_bound_rect; + GpRect gp_output_area; + RECT output_area; + INT output_height, output_width; + DWORD *output_bits, *brush_bits=NULL; + int i; + static const BYTE static_dash_pattern[] = {1,1,1,0,1,0,1,0}; + const BYTE *dash_pattern; + INT dash_pattern_size; + BYTE *dyn_dash_pattern = NULL; + + stat = GdipClonePath(path, &flat_path); + + if (stat != Ok) + return stat; + + stat = GdipCreateMatrix(&transform); + + if (stat == Ok) + { + stat = get_graphics_transform(graphics, CoordinateSpaceDevice, + CoordinateSpaceWorld, transform); + + if (stat == Ok) + stat = GdipFlattenPath(flat_path, transform, 1.0); + + GdipDeleteMatrix(transform); + } + + /* estimate the output size in pixels, can be larger than necessary */ + if (stat == Ok) + { + output_area.left = floorf(flat_path->pathdata.Points[0].X); + output_area.right = ceilf(flat_path->pathdata.Points[0].X); + output_area.top = floorf(flat_path->pathdata.Points[0].Y); + output_area.bottom = ceilf(flat_path->pathdata.Points[0].Y); + + for (i=1; ipathdata.Count; i++) + { + REAL x, y; + x = flat_path->pathdata.Points[i].X; + y = flat_path->pathdata.Points[i].Y; + + if (floorf(x) < output_area.left) output_area.left = floorf(x); + if (floorf(y) < output_area.top) output_area.top = floorf(y); + if (ceilf(x) > output_area.right) output_area.right = ceilf(x); + if (ceilf(y) > output_area.bottom) output_area.bottom = ceilf(y); + } + + stat = get_graphics_bounds(graphics, &gp_bound_rect); + } + + if (stat == Ok) + { + output_area.left = max(output_area.left, floorf(gp_bound_rect.X)); + output_area.top = max(output_area.top, floorf(gp_bound_rect.Y)); + output_area.right = min(output_area.right, ceilf(gp_bound_rect.X + gp_bound_rect.Width)); + output_area.bottom = min(output_area.bottom, ceilf(gp_bound_rect.Y + gp_bound_rect.Height)); + + output_width = output_area.right - output_area.left + 1; + output_height = output_area.bottom - output_area.top + 1; + + if (output_width <= 0 || output_height <= 0) + { + GdipDeletePath(flat_path); + return Ok; + } + + gp_output_area.X = output_area.left; + gp_output_area.Y = output_area.top; + gp_output_area.Width = output_width; + gp_output_area.Height = output_height; + + output_bits = heap_alloc_zero(output_width * output_height * sizeof(DWORD)); + if (!output_bits) + stat = OutOfMemory; + } + + if (stat == Ok) + { + if (pen->brush->bt != BrushTypeSolidColor) + { + /* allocate and draw brush output */ + brush_bits = heap_alloc_zero(output_width * output_height * sizeof(DWORD)); + + if (brush_bits) + { + stat = brush_fill_pixels(graphics, pen->brush, brush_bits, + &gp_output_area, output_width); + } + else + stat = OutOfMemory; + } + + if (stat == Ok) + { + /* convert dash pattern to bool array */ + switch (pen->dash) + { + case DashStyleCustom: + { + dash_pattern_size = 0; + + for (i=0; i < pen->numdashes; i++) + dash_pattern_size += gdip_round(pen->dashes[i]); + + if (dash_pattern_size != 0) + { + dash_pattern = dyn_dash_pattern = heap_alloc(dash_pattern_size); + + if (dyn_dash_pattern) + { + int j=0; + for (i=0; i < pen->numdashes; i++) + { + int k; + for (k=0; k < gdip_round(pen->dashes[i]); k++) + dyn_dash_pattern[j++] = (i&1)^1; + } + } + else + stat = OutOfMemory; + + break; + } + /* else fall through */ + } + case DashStyleSolid: + default: + dash_pattern = static_dash_pattern; + dash_pattern_size = 1; + break; + case DashStyleDash: + dash_pattern = static_dash_pattern; + dash_pattern_size = 4; + break; + case DashStyleDot: + dash_pattern = &static_dash_pattern[4]; + dash_pattern_size = 2; + break; + case DashStyleDashDot: + dash_pattern = static_dash_pattern; + dash_pattern_size = 6; + break; + case DashStyleDashDotDot: + dash_pattern = static_dash_pattern; + dash_pattern_size = 8; + break; + } + } + + if (stat == Ok) + { + /* trace path */ + GpPointF subpath_start = flat_path->pathdata.Points[0]; + INT prev_x = INT_MAX, prev_y = INT_MAX; + int dash_pos = dash_pattern_size - 1; + + for (i=0; i < flat_path->pathdata.Count; i++) + { + BYTE type, type2; + GpPointF start_point, end_point; + GpPoint start_pointi, end_pointi; + + type = flat_path->pathdata.Types[i]; + if (i+1 < flat_path->pathdata.Count) + type2 = flat_path->pathdata.Types[i+1]; + else + type2 = PathPointTypeStart; + + start_point = flat_path->pathdata.Points[i]; + + if ((type & PathPointTypePathTypeMask) == PathPointTypeStart) + subpath_start = start_point; + + if ((type & PathPointTypeCloseSubpath) == PathPointTypeCloseSubpath) + end_point = subpath_start; + else if ((type2 & PathPointTypePathTypeMask) == PathPointTypeStart) + continue; + else + end_point = flat_path->pathdata.Points[i+1]; + + start_pointi.X = floorf(start_point.X); + start_pointi.Y = floorf(start_point.Y); + end_pointi.X = floorf(end_point.X); + end_pointi.Y = floorf(end_point.Y); + + /* draw line segment */ + if (abs(start_pointi.Y - end_pointi.Y) > abs(start_pointi.X - end_pointi.X)) + { + INT x, y, start_y, end_y, step; + + if (start_pointi.Y < end_pointi.Y) + { + step = 1; + start_y = ceilf(start_point.Y) - output_area.top; + end_y = end_pointi.Y - output_area.top; + } + else + { + step = -1; + start_y = start_point.Y - output_area.top; + end_y = ceilf(end_point.Y) - output_area.top; + } + + for (y=start_y; y != (end_y+step); y+=step) + { + x = gdip_round( start_point.X + + (end_point.X - start_point.X) * (y + output_area.top - start_point.Y) / (end_point.Y - start_point.Y) ) + - output_area.left; + + if (x == prev_x && y == prev_y) + continue; + + prev_x = x; + prev_y = y; + dash_pos = (dash_pos + 1 == dash_pattern_size) ? 0 : dash_pos + 1; + + if (!dash_pattern[dash_pos]) + continue; + + if (x < 0 || x >= output_width || y < 0 || y >= output_height) + continue; + + if (brush_bits) + output_bits[x + y*output_width] = brush_bits[x + y*output_width]; + else + output_bits[x + y*output_width] = ((GpSolidFill*)pen->brush)->color; + } + } + else + { + INT x, y, start_x, end_x, step; + + if (start_pointi.X < end_pointi.X) + { + step = 1; + start_x = ceilf(start_point.X) - output_area.left; + end_x = end_pointi.X - output_area.left; + } + else + { + step = -1; + start_x = start_point.X - output_area.left; + end_x = ceilf(end_point.X) - output_area.left; + } + + for (x=start_x; x != (end_x+step); x+=step) + { + y = gdip_round( start_point.Y + + (end_point.Y - start_point.Y) * (x + output_area.left - start_point.X) / (end_point.X - start_point.X) ) + - output_area.top; + + if (x == prev_x && y == prev_y) + continue; + + prev_x = x; + prev_y = y; + dash_pos = (dash_pos + 1 == dash_pattern_size) ? 0 : dash_pos + 1; + + if (!dash_pattern[dash_pos]) + continue; + + if (x < 0 || x >= output_width || y < 0 || y >= output_height) + continue; + + if (brush_bits) + output_bits[x + y*output_width] = brush_bits[x + y*output_width]; + else + output_bits[x + y*output_width] = ((GpSolidFill*)pen->brush)->color; + } + } + } + } + + /* draw output image */ + if (stat == Ok) + { + stat = alpha_blend_pixels(graphics, output_area.left, output_area.top, + (BYTE*)output_bits, output_width, output_height, output_width * 4, + PixelFormat32bppARGB); + } + + heap_free(brush_bits); + heap_free(dyn_dash_pattern); + heap_free(output_bits); + } + + GdipDeletePath(flat_path); + + return stat; +} + GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) { GpStatus stat; GpPath *wide_path; GpMatrix *transform=NULL; + /* Check if the final pen thickness in pixels is too thin. */ + if (pen->unit == UnitPixel) + { + if (pen->width < 1.415) + return SOFTWARE_GdipDrawThinPath(graphics, pen, path); + } + else + { + GpPointF points[3] = {{0,0}, {1,0}, {0,1}}; + + points[1].X = pen->width; + points[2].Y = pen->width; + + stat = GdipTransformPoints(graphics, CoordinateSpaceDevice, + CoordinateSpaceWorld, points, 3); + + if (stat != Ok) + return stat; + + if (((points[1].X-points[0].X)*(points[1].X-points[0].X) + + (points[1].Y-points[0].Y)*(points[1].Y-points[0].Y) < 2.0001) && + ((points[2].X-points[0].X)*(points[2].X-points[0].X) + + (points[2].Y-points[0].Y)*(points[2].Y-points[0].Y) < 2.0001)) + return SOFTWARE_GdipDrawThinPath(graphics, pen, path); + } + stat = GdipClonePath(path, &wide_path); if (stat != Ok) -- 2.7.4 From aurimas at members.fsf.org Thu Oct 13 14:36:45 2016 From: aurimas at members.fsf.org (=?UTF-8?Q?Aurimas_Fi=c5=a1eras?=) Date: Thu, 13 Oct 2016 22:36:45 +0300 Subject: po: Update Lithuanian translation Message-ID: A non-text attachment was scrubbed... Name: 0001-po-Update-Lithuanian-translation.patch Type: text/x-patch Size: 1156 bytes Desc: not available URL: From madewokherd at gmail.com Thu Oct 13 16:23:13 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Thu, 13 Oct 2016 16:23:13 -0500 Subject: [v2 1/5] gdiplus: Allow widening a "closed" line segment. Message-ID: <1476393797-12773-1-git-send-email-madewokherd@gmail.com> From: Vincent Povirk Turns out native allows this. I did this in my updated test case in patch 3, to draw two disconnected lines in one path. Signed-off-by: Vincent Povirk --- dlls/gdiplus/graphicspath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 963ee1c..8ba0016 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -1888,7 +1888,7 @@ static void widen_closed_figure(GpPath *path, GpPen *pen, int start, int end, int i; path_list_node_t *prev_point; - if (end <= start+1) + if (end <= start) return; /* left outline */ -- 2.7.4 From madewokherd at gmail.com Thu Oct 13 16:23:15 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Thu, 13 Oct 2016 16:23:15 -0500 Subject: [v2 3/5] gdiplus/tests: Add tests for 0-pixel pens. Message-ID: <1476393797-12773-3-git-send-email-madewokherd@gmail.com> From: Vincent Povirk It turns out that GdipDrawLine behaves differently from GdipDrawPath, only in the case of a 0 pixel pen. So I added a GdipDrawPath test, and more cases of very thin lines, since v1. I think it would have been better to have a detailed test of GdipDrawPath, and a less detailed test case showing GdipDrawLine is different, but I don't like to remove it now that it's there. Signed-off-by: Vincent Povirk --- dlls/gdiplus/tests/graphics.c | 94 ++++++++++++++++++++++++++++++++++++--- dlls/gdiplus/tests/graphicspath.c | 18 ++++++++ 2 files changed, 105 insertions(+), 7 deletions(-) diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c index d86f49d..529f1a2 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -3899,15 +3899,18 @@ static void test_pen_thickness(void) REAL res_x, res_y, scale; GpUnit pen_unit, page_unit; REAL pen_width; - INT cx, cy; + INT cx, cy, path_cx, path_cy; } td[] = { - { 10.0, 10.0, 1.0, UnitPixel, UnitPixel, 1.0, 1, 1 }, - { 10.0, 10.0, 3.0, UnitPixel, UnitPixel, 2.0, 2, 2 }, - { 10.0, 10.0, 30.0, UnitPixel, UnitInch, 1.0, 1, 1 }, - { 10.0, 10.0, 1.0, UnitWorld, UnitPixel, 1.0, 1, 1 }, - { 10.0, 10.0, 3.0, UnitWorld, UnitPixel, 2.0, 6, 6 }, - { 10.0, 10.0, 2.0, UnitWorld, UnitInch, 1.0, 20, 20 }, + { 10.0, 10.0, 1.0, UnitPixel, UnitPixel, 1.0, 1, 1, 1, 1 }, + { 10.0, 10.0, 1.0, UnitPixel, UnitPixel, 0.0, 0, 0, 1, 1 }, + { 10.0, 10.0, 1.0, UnitPixel, UnitPixel, 0.1, 1, 1, 1, 1 }, + { 10.0, 10.0, 3.0, UnitPixel, UnitPixel, 2.0, 2, 2, 2, 2 }, + { 10.0, 10.0, 30.0, UnitPixel, UnitInch, 1.0, 1, 1, 1, 1 }, + { 10.0, 10.0, 1.0, UnitWorld, UnitPixel, 1.0, 1, 1, 1, 1 }, + { 10.0, 10.0, 1.0, UnitWorld, UnitPixel, 0.0, 1, 1, 1, 1 }, + { 10.0, 10.0, 3.0, UnitWorld, UnitPixel, 2.0, 6, 6, 6, 6 }, + { 10.0, 10.0, 2.0, UnitWorld, UnitInch, 1.0, 20, 20, 20, 20 }, }; GpStatus status; int i, j; @@ -3919,6 +3922,7 @@ static void test_pen_thickness(void) } u; GpPen *pen; GpPointF corner; + GpPath *path; BitmapData bd; INT min, max, size; @@ -4008,6 +4012,82 @@ static void test_pen_thickness(void) status = GdipBitmapUnlockBits(u.bitmap, &bd); expect(Ok, status); + status = GdipGraphicsClear(graphics, 0xff000000); + expect(Ok, status); + + status = GdipCreatePath(FillModeAlternate, &path); + expect(Ok, status); + + status = GdipAddPathLine(path, corner.X/2, 0, corner.X/2, corner.Y); + expect(Ok, status); + + status = GdipClosePathFigure(path); + expect(Ok, status); + + status = GdipAddPathLine(path, 0, corner.Y/2, corner.X, corner.Y/2); + expect(Ok, status); + + status = GdipDrawPath(graphics, pen, path); + expect(Ok, status); + + GdipDeletePath(path); + + status = GdipBitmapLockBits(u.bitmap, NULL, ImageLockModeRead, PixelFormat24bppRGB, &bd); + expect(Ok, status); + + min = -1; + max = -2; + + for (j=0; j<100; j++) + { + if (((BYTE*)bd.Scan0)[j*3] == 0xff) + { + min = j; + break; + } + } + + for (j=99; j>=0; j--) + { + if (((BYTE*)bd.Scan0)[j*3] == 0xff) + { + max = j; + break; + } + } + + size = max-min+1; + + ok(size == td[i].path_cx, "%u: expected %d, got %d\n", i, td[i].path_cx, size); + + min = -1; + max = -2; + + for (j=0; j<100; j++) + { + if (((BYTE*)bd.Scan0)[bd.Stride*j] == 0xff) + { + min = j; + break; + } + } + + for (j=99; j>=0; j--) + { + if (((BYTE*)bd.Scan0)[bd.Stride*j] == 0xff) + { + max = j; + break; + } + } + + size = max-min+1; + + ok(size == td[i].path_cy, "%u: expected %d, got %d\n", i, td[i].path_cy, size); + + status = GdipBitmapUnlockBits(u.bitmap, &bd); + expect(Ok, status); + GdipDeletePen(pen); GdipDeleteGraphics(graphics); GdipDisposeImage(u.image); diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index c43fb42..c44ed5e 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -1071,6 +1071,7 @@ static void test_widen(void) GpPath *path; GpPen *pen; GpMatrix *m; + INT count=-1; status = GdipCreatePath(FillModeAlternate, &path); expect(Ok, status); @@ -1195,6 +1196,23 @@ static void test_widen(void) expect(Ok, status); ok_path(path, widenline_path, sizeof(widenline_path)/sizeof(path_test_t), FALSE); + /* pen width = 0 pixels - native fails to widen but can draw with this pen */ + GdipDeletePen(pen); + status = GdipCreatePen1(0xffffffff, 0.0, UnitPixel, &pen); + expect(Ok, status); + + status = GdipResetPath(path); + expect(Ok, status); + status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0); + expect(Ok, status); + + status = GdipWidenPath(path, pen, m, 1.0); + expect(Ok, status); + + status = GdipGetPointCount(path, &count); + expect(Ok, status); + todo_wine expect(0, count); + GdipDeleteMatrix(m); GdipDeletePen(pen); GdipDeletePath(path); -- 2.7.4 From madewokherd at gmail.com Thu Oct 13 16:23:17 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Thu, 13 Oct 2016 16:23:17 -0500 Subject: [v2 5/5] gdiplus: Add a software path for thin line drawing. Message-ID: <1476393797-12773-5-git-send-email-madewokherd@gmail.com> From: Vincent Povirk Unchanged since v1. Signed-off-by: Vincent Povirk --- dlls/gdiplus/graphics.c | 324 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 56faa16..324c06f 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -3401,12 +3401,336 @@ end: return retval; } +GpStatus SOFTWARE_GdipDrawThinPath(GpGraphics *graphics, GpPen *pen, GpPath *path) +{ + GpStatus stat; + GpPath* flat_path; + GpMatrix* transform; + GpRectF gp_bound_rect; + GpRect gp_output_area; + RECT output_area; + INT output_height, output_width; + DWORD *output_bits, *brush_bits=NULL; + int i; + static const BYTE static_dash_pattern[] = {1,1,1,0,1,0,1,0}; + const BYTE *dash_pattern; + INT dash_pattern_size; + BYTE *dyn_dash_pattern = NULL; + + stat = GdipClonePath(path, &flat_path); + + if (stat != Ok) + return stat; + + stat = GdipCreateMatrix(&transform); + + if (stat == Ok) + { + stat = get_graphics_transform(graphics, CoordinateSpaceDevice, + CoordinateSpaceWorld, transform); + + if (stat == Ok) + stat = GdipFlattenPath(flat_path, transform, 1.0); + + GdipDeleteMatrix(transform); + } + + /* estimate the output size in pixels, can be larger than necessary */ + if (stat == Ok) + { + output_area.left = floorf(flat_path->pathdata.Points[0].X); + output_area.right = ceilf(flat_path->pathdata.Points[0].X); + output_area.top = floorf(flat_path->pathdata.Points[0].Y); + output_area.bottom = ceilf(flat_path->pathdata.Points[0].Y); + + for (i=1; ipathdata.Count; i++) + { + REAL x, y; + x = flat_path->pathdata.Points[i].X; + y = flat_path->pathdata.Points[i].Y; + + if (floorf(x) < output_area.left) output_area.left = floorf(x); + if (floorf(y) < output_area.top) output_area.top = floorf(y); + if (ceilf(x) > output_area.right) output_area.right = ceilf(x); + if (ceilf(y) > output_area.bottom) output_area.bottom = ceilf(y); + } + + stat = get_graphics_bounds(graphics, &gp_bound_rect); + } + + if (stat == Ok) + { + output_area.left = max(output_area.left, floorf(gp_bound_rect.X)); + output_area.top = max(output_area.top, floorf(gp_bound_rect.Y)); + output_area.right = min(output_area.right, ceilf(gp_bound_rect.X + gp_bound_rect.Width)); + output_area.bottom = min(output_area.bottom, ceilf(gp_bound_rect.Y + gp_bound_rect.Height)); + + output_width = output_area.right - output_area.left + 1; + output_height = output_area.bottom - output_area.top + 1; + + if (output_width <= 0 || output_height <= 0) + { + GdipDeletePath(flat_path); + return Ok; + } + + gp_output_area.X = output_area.left; + gp_output_area.Y = output_area.top; + gp_output_area.Width = output_width; + gp_output_area.Height = output_height; + + output_bits = heap_alloc_zero(output_width * output_height * sizeof(DWORD)); + if (!output_bits) + stat = OutOfMemory; + } + + if (stat == Ok) + { + if (pen->brush->bt != BrushTypeSolidColor) + { + /* allocate and draw brush output */ + brush_bits = heap_alloc_zero(output_width * output_height * sizeof(DWORD)); + + if (brush_bits) + { + stat = brush_fill_pixels(graphics, pen->brush, brush_bits, + &gp_output_area, output_width); + } + else + stat = OutOfMemory; + } + + if (stat == Ok) + { + /* convert dash pattern to bool array */ + switch (pen->dash) + { + case DashStyleCustom: + { + dash_pattern_size = 0; + + for (i=0; i < pen->numdashes; i++) + dash_pattern_size += gdip_round(pen->dashes[i]); + + if (dash_pattern_size != 0) + { + dash_pattern = dyn_dash_pattern = heap_alloc(dash_pattern_size); + + if (dyn_dash_pattern) + { + int j=0; + for (i=0; i < pen->numdashes; i++) + { + int k; + for (k=0; k < gdip_round(pen->dashes[i]); k++) + dyn_dash_pattern[j++] = (i&1)^1; + } + } + else + stat = OutOfMemory; + + break; + } + /* else fall through */ + } + case DashStyleSolid: + default: + dash_pattern = static_dash_pattern; + dash_pattern_size = 1; + break; + case DashStyleDash: + dash_pattern = static_dash_pattern; + dash_pattern_size = 4; + break; + case DashStyleDot: + dash_pattern = &static_dash_pattern[4]; + dash_pattern_size = 2; + break; + case DashStyleDashDot: + dash_pattern = static_dash_pattern; + dash_pattern_size = 6; + break; + case DashStyleDashDotDot: + dash_pattern = static_dash_pattern; + dash_pattern_size = 8; + break; + } + } + + if (stat == Ok) + { + /* trace path */ + GpPointF subpath_start = flat_path->pathdata.Points[0]; + INT prev_x = INT_MAX, prev_y = INT_MAX; + int dash_pos = dash_pattern_size - 1; + + for (i=0; i < flat_path->pathdata.Count; i++) + { + BYTE type, type2; + GpPointF start_point, end_point; + GpPoint start_pointi, end_pointi; + + type = flat_path->pathdata.Types[i]; + if (i+1 < flat_path->pathdata.Count) + type2 = flat_path->pathdata.Types[i+1]; + else + type2 = PathPointTypeStart; + + start_point = flat_path->pathdata.Points[i]; + + if ((type & PathPointTypePathTypeMask) == PathPointTypeStart) + subpath_start = start_point; + + if ((type & PathPointTypeCloseSubpath) == PathPointTypeCloseSubpath) + end_point = subpath_start; + else if ((type2 & PathPointTypePathTypeMask) == PathPointTypeStart) + continue; + else + end_point = flat_path->pathdata.Points[i+1]; + + start_pointi.X = floorf(start_point.X); + start_pointi.Y = floorf(start_point.Y); + end_pointi.X = floorf(end_point.X); + end_pointi.Y = floorf(end_point.Y); + + /* draw line segment */ + if (abs(start_pointi.Y - end_pointi.Y) > abs(start_pointi.X - end_pointi.X)) + { + INT x, y, start_y, end_y, step; + + if (start_pointi.Y < end_pointi.Y) + { + step = 1; + start_y = ceilf(start_point.Y) - output_area.top; + end_y = end_pointi.Y - output_area.top; + } + else + { + step = -1; + start_y = start_point.Y - output_area.top; + end_y = ceilf(end_point.Y) - output_area.top; + } + + for (y=start_y; y != (end_y+step); y+=step) + { + x = gdip_round( start_point.X + + (end_point.X - start_point.X) * (y + output_area.top - start_point.Y) / (end_point.Y - start_point.Y) ) + - output_area.left; + + if (x == prev_x && y == prev_y) + continue; + + prev_x = x; + prev_y = y; + dash_pos = (dash_pos + 1 == dash_pattern_size) ? 0 : dash_pos + 1; + + if (!dash_pattern[dash_pos]) + continue; + + if (x < 0 || x >= output_width || y < 0 || y >= output_height) + continue; + + if (brush_bits) + output_bits[x + y*output_width] = brush_bits[x + y*output_width]; + else + output_bits[x + y*output_width] = ((GpSolidFill*)pen->brush)->color; + } + } + else + { + INT x, y, start_x, end_x, step; + + if (start_pointi.X < end_pointi.X) + { + step = 1; + start_x = ceilf(start_point.X) - output_area.left; + end_x = end_pointi.X - output_area.left; + } + else + { + step = -1; + start_x = start_point.X - output_area.left; + end_x = ceilf(end_point.X) - output_area.left; + } + + for (x=start_x; x != (end_x+step); x+=step) + { + y = gdip_round( start_point.Y + + (end_point.Y - start_point.Y) * (x + output_area.left - start_point.X) / (end_point.X - start_point.X) ) + - output_area.top; + + if (x == prev_x && y == prev_y) + continue; + + prev_x = x; + prev_y = y; + dash_pos = (dash_pos + 1 == dash_pattern_size) ? 0 : dash_pos + 1; + + if (!dash_pattern[dash_pos]) + continue; + + if (x < 0 || x >= output_width || y < 0 || y >= output_height) + continue; + + if (brush_bits) + output_bits[x + y*output_width] = brush_bits[x + y*output_width]; + else + output_bits[x + y*output_width] = ((GpSolidFill*)pen->brush)->color; + } + } + } + } + + /* draw output image */ + if (stat == Ok) + { + stat = alpha_blend_pixels(graphics, output_area.left, output_area.top, + (BYTE*)output_bits, output_width, output_height, output_width * 4, + PixelFormat32bppARGB); + } + + heap_free(brush_bits); + heap_free(dyn_dash_pattern); + heap_free(output_bits); + } + + GdipDeletePath(flat_path); + + return stat; +} + GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) { GpStatus stat; GpPath *wide_path; GpMatrix *transform=NULL; + /* Check if the final pen thickness in pixels is too thin. */ + if (pen->unit == UnitPixel) + { + if (pen->width < 1.415) + return SOFTWARE_GdipDrawThinPath(graphics, pen, path); + } + else + { + GpPointF points[3] = {{0,0}, {1,0}, {0,1}}; + + points[1].X = pen->width; + points[2].Y = pen->width; + + stat = GdipTransformPoints(graphics, CoordinateSpaceDevice, + CoordinateSpaceWorld, points, 3); + + if (stat != Ok) + return stat; + + if (((points[1].X-points[0].X)*(points[1].X-points[0].X) + + (points[1].Y-points[0].Y)*(points[1].Y-points[0].Y) < 2.0001) && + ((points[2].X-points[0].X)*(points[2].X-points[0].X) + + (points[2].Y-points[0].Y)*(points[2].Y-points[0].Y) < 2.0001)) + return SOFTWARE_GdipDrawThinPath(graphics, pen, path); + } + stat = GdipClonePath(path, &wide_path); if (stat != Ok) -- 2.7.4 From madewokherd at gmail.com Thu Oct 13 16:23:16 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Thu, 13 Oct 2016 16:23:16 -0500 Subject: [v2 4/5] gdiplus: Add non-gdi32 implementation of GdipDrawPath. Message-ID: <1476393797-12773-4-git-send-email-madewokherd@gmail.com> From: Vincent Povirk Unchanged since v1. Signed-off-by: Vincent Povirk --- dlls/gdiplus/graphics.c | 84 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 15 deletions(-) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index c75618c..56faa16 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -3375,26 +3375,12 @@ GpStatus WINGDIPAPI GdipDrawLinesI(GpGraphics *graphics, GpPen *pen, GDIPCONST return retval; } -GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) +GpStatus GDI32_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) { INT save_state; GpStatus retval; HRGN hrgn=NULL; - TRACE("(%p, %p, %p)\n", graphics, pen, path); - - if(!pen || !graphics) - return InvalidParameter; - - if(graphics->busy) - return ObjectBusy; - - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } - save_state = prepare_dc(graphics, pen); retval = get_clip_hrgn(graphics, &hrgn); @@ -3415,6 +3401,74 @@ end: return retval; } +GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) +{ + GpStatus stat; + GpPath *wide_path; + GpMatrix *transform=NULL; + + stat = GdipClonePath(path, &wide_path); + + if (stat != Ok) + return stat; + + if (pen->unit == UnitPixel) + { + /* We have to transform this to device coordinates to get the widths right. */ + stat = GdipCreateMatrix(&transform); + + if (stat == Ok) + stat = get_graphics_transform(graphics, CoordinateSpaceDevice, + CoordinateSpaceWorld, transform); + } + + if (stat == Ok) + stat = GdipWidenPath(wide_path, pen, transform, 1.0); + + if (pen->unit == UnitPixel) + { + /* Transform the path back to world coordinates */ + if (stat == Ok) + stat = GdipInvertMatrix(transform); + + if (stat == Ok) + stat = GdipTransformPath(wide_path, transform); + } + + /* Actually draw the path */ + if (stat == Ok) + stat = GdipFillPath(graphics, pen->brush, wide_path); + + GdipDeleteMatrix(transform); + + GdipDeletePath(wide_path); + + return stat; +} + +GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) +{ + GpStatus retval; + + TRACE("(%p, %p, %p)\n", graphics, pen, path); + + if(!pen || !graphics) + return InvalidParameter; + + if(graphics->busy) + return ObjectBusy; + + if (path->pathdata.Count == 0) + return Ok; + + if (!graphics->hdc) + retval = SOFTWARE_GdipDrawPath(graphics, pen, path); + else + retval = GDI32_GdipDrawPath(graphics, pen, path); + + return retval; +} + GpStatus WINGDIPAPI GdipDrawPie(GpGraphics *graphics, GpPen *pen, REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle) { -- 2.7.4 From madewokherd at gmail.com Thu Oct 13 16:23:14 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Thu, 13 Oct 2016 16:23:14 -0500 Subject: [v2 2/5] gdiplus: GdipDrawLine ignores 0-pixel pens. Message-ID: <1476393797-12773-2-git-send-email-madewokherd@gmail.com> From: Vincent Povirk Signed-off-by: Vincent Povirk --- dlls/gdiplus/graphics.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 076ed81..c75618c 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -3306,6 +3306,12 @@ GpStatus WINGDIPAPI GdipDrawLine(GpGraphics *graphics, GpPen *pen, REAL x1, TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f)\n", graphics, pen, x1, y1, x2, y2); + if (!pen) + return InvalidParameter; + + if (pen->unit == UnitPixel && pen->width <= 0.0) + return Ok; + pt[0].X = x1; pt[0].Y = y1; pt[1].X = x2; -- 2.7.4 From mbruni at codeweavers.com Thu Oct 13 17:03:33 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Fri, 14 Oct 2016 00:03:33 +0200 Subject: [PATCH 1/5] wined3d: Add a quirk for GL implementations not supporting sRGB FBO attachments. Message-ID: <1476396217-26826-1-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- As it seems to be the case for i915 (at least with some Mesa versions). This is only a problem because the GL implementation also exposes EXT_texture_sRGB_decode and when that extension is available we always use the sRGB format. For bug 41052. dlls/wined3d/directx.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 5d324f3..052321a 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -887,6 +887,37 @@ static BOOL match_broken_arb_fog(const struct wined3d_gl_info *gl_info, const ch return data[0] != 0x00ff0000 || data[3] != 0x0000ff00; } +static BOOL match_no_srgb_fbo_attachments(const struct wined3d_gl_info *gl_info, const char *gl_renderer, + enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + GLuint fbo, rb; + GLenum status; + + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) + return FALSE; + if (!gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) + return FALSE; + + gl_info->fbo_ops.glGenFramebuffers(1, &fbo); + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); + gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0); + gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0); + + gl_info->fbo_ops.glGenRenderbuffers(1, &rb); + gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb); + gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_SRGB8_ALPHA8, 16, 16); + gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); + + status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); + TRACE("Framebuffer status %s (%#x).\n", debug_fbostatus(status), status); + + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0); + gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); + gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb); + + return status != GL_FRAMEBUFFER_COMPLETE; +} + static void quirk_apple_glsl_constants(struct wined3d_gl_info *gl_info) { /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms. @@ -1015,6 +1046,12 @@ static void quirk_broken_arb_fog(struct wined3d_gl_info *gl_info) gl_info->quirks |= WINED3D_QUIRK_BROKEN_ARB_FOG; } +static void quirk_no_srgb_fbo_attachments(struct wined3d_gl_info *gl_info) +{ + TRACE("sRGB FBO attachments not supported, disabling EXT_texture_sRGB_decode codepaths.\n"); + gl_info->supported[EXT_TEXTURE_SRGB_DECODE] = FALSE; +} + struct driver_quirk { BOOL (*match)(const struct wined3d_gl_info *gl_info, const char *gl_renderer, @@ -1105,6 +1142,11 @@ static const struct driver_quirk quirk_table[] = quirk_broken_arb_fog, "ARBfp fogstart == fogend workaround" }, + { + match_no_srgb_fbo_attachments, + quirk_no_srgb_fbo_attachments, + "sRGB FBO attachments unavailable" + }, }; /* Certain applications (Steam) complain if we report an outdated driver version. In general, @@ -3836,6 +3878,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD /* Current wined3d sRGB infrastructure requires EXT_texture_sRGB_decode * for GL_ARB_framebuffer_sRGB support (without EXT_texture_sRGB_decode * we never render to sRGB surfaces). */ + TRACE("EXT_texture_sRGB_decode is not supported, disabling ARB_framebuffer_sRGB.\n"); gl_info->supported[ARB_FRAMEBUFFER_SRGB] = FALSE; } if (gl_info->supported[ARB_OCCLUSION_QUERY]) -- 2.7.3 From mbruni at codeweavers.com Thu Oct 13 17:03:34 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Fri, 14 Oct 2016 00:03:34 +0200 Subject: [PATCH 2/5] wined3d: Recognize a couple of Haswell / Broadwell GPUs on macOS. In-Reply-To: <1476396217-26826-1-git-send-email-mbruni@codeweavers.com> References: <1476396217-26826-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1476396217-26826-2-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- Not strictly necessary, we should be able to use the Mac implementation of WGL_WINE_query_renderer just fine. dlls/wined3d/directx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 052321a..a495d01 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2077,8 +2077,10 @@ cards_intel[] = {"Iris Pro P6300", CARD_INTEL_IPP6300}, {"Iris Pro 6200", CARD_INTEL_IP6200}, {"Iris 6100", CARD_INTEL_IG6100}, + {"Iris(TM) Graphics 6100", CARD_INTEL_IG6100}, /* MacOS */ /* Haswell */ {"Haswell Mobile", CARD_INTEL_HWM}, + {"Iris OpenGL Engine", CARD_INTEL_HWM}, /* MacOS */ /* Ivybridge */ {"Ivybridge Server", CARD_INTEL_IVBS}, {"Ivybridge Mobile", CARD_INTEL_IVBM}, -- 2.7.3 From mbruni at codeweavers.com Thu Oct 13 17:03:35 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Fri, 14 Oct 2016 00:03:35 +0200 Subject: [PATCH 3/5] wined3d: Add a bunch of Broadwell and Skylake PCI ids and descriptions. In-Reply-To: <1476396217-26826-1-git-send-email-mbruni@codeweavers.com> References: <1476396217-26826-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1476396217-26826-3-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- I'm not adding new entries to cards_intel[] because they shouldn't be necessary for either Mesa or macOS (also I don't know the macOS strings). I could add the Mesa strings "just because", though. dlls/wined3d/directx.c | 32 ++++++++++++++++++++++++-------- dlls/wined3d/wined3d_private.h | 24 ++++++++++++++++++++---- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index a495d01..24fb9e5 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -1450,14 +1450,30 @@ static const struct gpu_description gpu_description_table[] = {HW_VENDOR_INTEL, CARD_INTEL_IVBS, "Intel(R) HD Graphics Family", DRIVER_INTEL_HD4000, 1536}, {HW_VENDOR_INTEL, CARD_INTEL_HWD, "Intel(R) HD Graphics 4600", DRIVER_INTEL_HD4000, 1536}, {HW_VENDOR_INTEL, CARD_INTEL_HWM, "Intel(R) HD Graphics 4600", DRIVER_INTEL_HD4000, 1536}, - {HW_VENDOR_INTEL, CARD_INTEL_IG6100, "Intel(R) Iris(TM) Graphics 6100", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD5300, "Intel(R) HD Graphics 5300", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD5500, "Intel(R) HD Graphics 5500", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD5600, "Intel(R) HD Graphics 5600", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD6000, "Intel(R) HD Graphics 6000", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_I6100, "Intel(R) Iris(TM) Graphics 6100", DRIVER_INTEL_HD4000, 2048}, {HW_VENDOR_INTEL, CARD_INTEL_IP6200, "Intel(R) Iris(TM) Pro Graphics 6200", DRIVER_INTEL_HD4000, 2048}, {HW_VENDOR_INTEL, CARD_INTEL_IPP6300, "Intel(R) Iris(TM) Pro Graphics P6300", DRIVER_INTEL_HD4000, 2048}, - {HW_VENDOR_INTEL, CARD_INTEL_HD520, "Intel(R) HD Graphics 520", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD510_1, "Intel(R) HD Graphics 510", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD510_2, "Intel(R) HD Graphics 510", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD510_3, "Intel(R) HD Graphics 510", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD515, "Intel(R) HD Graphics 515", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD520_1, "Intel(R) HD Graphics 520", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HD520_2, "Intel(R) HD Graphics 520", DRIVER_INTEL_HD4000, 2048}, {HW_VENDOR_INTEL, CARD_INTEL_HD530_1, "Intel(R) HD Graphics 530", DRIVER_INTEL_HD4000, 2048}, {HW_VENDOR_INTEL, CARD_INTEL_HD530_2, "Intel(R) HD Graphics 530", DRIVER_INTEL_HD4000, 2048}, - {HW_VENDOR_INTEL, CARD_INTEL_HD540, "Intel(R) Iris(TM) Graphics 540", DRIVER_INTEL_HD4000, 2048}, - {HW_VENDOR_INTEL, CARD_INTEL_IPP580, "Intel(R) Iris(TM) Pro Graphics P580", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_HDP530, "Intel(R) HD Graphics P530", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_I540, "Intel(R) Iris(TM) Graphics 540", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_I550, "Intel(R) Iris(TM) Graphics 550", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_I555, "Intel(R) Iris(TM) Graphics 555", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_IP555, "Intel(R) Iris(TM) Graphics P555", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_IP580_1, "Intel(R) Iris(TM) Pro Graphics 580", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_IP580_2, "Intel(R) Iris(TM) Pro Graphics 580", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_IPP580_1, "Intel(R) Iris(TM) Pro Graphics P580", DRIVER_INTEL_HD4000, 2048}, + {HW_VENDOR_INTEL, CARD_INTEL_IPP580_2, "Intel(R) Iris(TM) Pro Graphics P580", DRIVER_INTEL_HD4000, 2048}, }; static const struct driver_version_information *get_driver_version_info(enum wined3d_display_driver driver, @@ -2071,13 +2087,13 @@ cards_amd_binary[] = cards_intel[] = { /* Skylake */ - {"Iris Pro Graphics P580", CARD_INTEL_IPP580}, - {"Skylake", CARD_INTEL_HD520}, + {"Iris Pro Graphics P580", CARD_INTEL_IPP580_1}, + {"Skylake", CARD_INTEL_HD520_1}, /* Broadwell */ {"Iris Pro P6300", CARD_INTEL_IPP6300}, {"Iris Pro 6200", CARD_INTEL_IP6200}, - {"Iris 6100", CARD_INTEL_IG6100}, - {"Iris(TM) Graphics 6100", CARD_INTEL_IG6100}, /* MacOS */ + {"Iris 6100", CARD_INTEL_I6100}, + {"Iris(TM) Graphics 6100", CARD_INTEL_I6100}, /* MacOS */ /* Haswell */ {"Haswell Mobile", CARD_INTEL_HWM}, {"Iris OpenGL Engine", CARD_INTEL_HWM}, /* MacOS */ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index a9800b3..4326bee 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2001,14 +2001,30 @@ enum wined3d_pci_device CARD_INTEL_IVBS = 0x015a, CARD_INTEL_HWD = 0x0412, CARD_INTEL_HWM = 0x0416, - CARD_INTEL_IG6100 = 0x162b, + CARD_INTEL_HD5300 = 0x161e, + CARD_INTEL_HD5500 = 0x1616, + CARD_INTEL_HD5600 = 0x1612, + CARD_INTEL_HD6000 = 0x1626, + CARD_INTEL_I6100 = 0x162b, CARD_INTEL_IP6200 = 0x1622, CARD_INTEL_IPP6300 = 0x162a, - CARD_INTEL_HD520 = 0x1916, + CARD_INTEL_HD510_1 = 0x1902, + CARD_INTEL_HD510_2 = 0x1906, + CARD_INTEL_HD510_3 = 0x190b, + CARD_INTEL_HD515 = 0x191e, + CARD_INTEL_HD520_1 = 0x1916, + CARD_INTEL_HD520_2 = 0x1921, CARD_INTEL_HD530_1 = 0x1912, CARD_INTEL_HD530_2 = 0x191b, - CARD_INTEL_HD540 = 0x1926, - CARD_INTEL_IPP580 = 0x193d, + CARD_INTEL_HDP530 = 0x191d, + CARD_INTEL_I540 = 0x1926, + CARD_INTEL_I550 = 0x1927, + CARD_INTEL_I555 = 0x192b, + CARD_INTEL_IP555 = 0x192d, + CARD_INTEL_IP580_1 = 0x1932, + CARD_INTEL_IP580_2 = 0x193b, + CARD_INTEL_IPP580_1 = 0x193a, + CARD_INTEL_IPP580_2 = 0x193d, }; struct wined3d_fbo_ops -- 2.7.3 From mbruni at codeweavers.com Thu Oct 13 17:03:36 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Fri, 14 Oct 2016 00:03:36 +0200 Subject: [PATCH 4/5] wined3d: Ignore driver model if the requested driver model entry is missing. In-Reply-To: <1476396217-26826-1-git-send-email-mbruni@codeweavers.com> References: <1476396217-26826-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1476396217-26826-4-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- We only have a DRIVER_MODEL_NT6X entry for DRIVER_INTEL_HD4000 and, going forward, it's likely we'll have more similar cases. It's essentially a different approach to commit f03c25699723ed03aa0b05e5d432a52402608f94 for fixing the same issue. Feel free to ignore this one, I just happened to have this patch around... dlls/wined3d/directx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 24fb9e5..5825aa5 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -61,6 +61,7 @@ enum wined3d_display_driver enum wined3d_driver_model { + DRIVER_MODEL_GENERIC, DRIVER_MODEL_WIN9X, DRIVER_MODEL_NT40, DRIVER_MODEL_NT5X, @@ -1486,7 +1487,8 @@ static const struct driver_version_information *get_driver_version_info(enum win { const struct driver_version_information *entry = &driver_version_table[i]; - if (entry->driver == driver && entry->driver_model == driver_model) + if (entry->driver == driver && (driver_model == DRIVER_MODEL_GENERIC + || entry->driver_model == driver_model)) { TRACE("Found driver \"%s\", version %u, subversion %u, build %u.\n", entry->driver_name, entry->version, entry->subversion, entry->build); @@ -1661,8 +1663,7 @@ static void init_driver_info(struct wined3d_driver_info *driver_info, * This could be an indication that our database is not up to date, so this should be fixed. */ if ((version_info = get_driver_version_info(driver, driver_model)) - || (version_info = get_driver_version_info(driver, DRIVER_MODEL_NT5X)) - || (version_info = get_driver_version_info(driver, DRIVER_MODEL_NT6X))) + || (version_info = get_driver_version_info(driver, DRIVER_MODEL_GENERIC))) { driver_info->name = version_info->driver_name; driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, version_info->version); -- 2.7.3 From mbruni at codeweavers.com Thu Oct 13 17:03:37 2016 From: mbruni at codeweavers.com (Matteo Bruni) Date: Fri, 14 Oct 2016 00:03:37 +0200 Subject: [PATCH 5/5] wined3d: Store blit quad texture coordinates in a struct wined3d_vec3 array. In-Reply-To: <1476396217-26826-1-git-send-email-mbruni@codeweavers.com> References: <1476396217-26826-1-git-send-email-mbruni@codeweavers.com> Message-ID: <1476396217-26826-5-git-send-email-mbruni@codeweavers.com> Signed-off-by: Matteo Bruni --- dlls/wined3d/surface.c | 102 ++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index d44d0ba..1c211ed 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -74,7 +74,7 @@ struct blt_info GLenum binding; GLenum bind_target; enum wined3d_gl_resource_type tex_type; - GLfloat coords[4][3]; + struct wined3d_vec3 texcoords[4]; }; struct float_rect @@ -95,43 +95,43 @@ static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLsizei h, struct blt_info *info) { - GLfloat (*coords)[3] = info->coords; + struct wined3d_vec3 *coords = info->texcoords; struct float_rect f; switch (target) { default: - FIXME("Unsupported texture target %#x\n", target); + FIXME("Unsupported texture target %#x.\n", target); /* Fall back to GL_TEXTURE_2D */ case GL_TEXTURE_2D: info->binding = GL_TEXTURE_BINDING_2D; info->bind_target = GL_TEXTURE_2D; info->tex_type = WINED3D_GL_RES_TYPE_TEX_2D; - coords[0][0] = (float)rect->left / w; - coords[0][1] = (float)rect->top / h; - coords[0][2] = 0.0f; + coords[0].x = (float)rect->left / w; + coords[0].y = (float)rect->top / h; + coords[0].z = 0.0f; - coords[1][0] = (float)rect->right / w; - coords[1][1] = (float)rect->top / h; - coords[1][2] = 0.0f; + coords[1].x = (float)rect->right / w; + coords[1].y = (float)rect->top / h; + coords[1].z = 0.0f; - coords[2][0] = (float)rect->left / w; - coords[2][1] = (float)rect->bottom / h; - coords[2][2] = 0.0f; + coords[2].x = (float)rect->left / w; + coords[2].y = (float)rect->bottom / h; + coords[2].z = 0.0f; - coords[3][0] = (float)rect->right / w; - coords[3][1] = (float)rect->bottom / h; - coords[3][2] = 0.0f; + coords[3].x = (float)rect->right / w; + coords[3].y = (float)rect->bottom / h; + coords[3].z = 0.0f; break; case GL_TEXTURE_RECTANGLE_ARB: info->binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; info->bind_target = GL_TEXTURE_RECTANGLE_ARB; info->tex_type = WINED3D_GL_RES_TYPE_TEX_RECT; - coords[0][0] = rect->left; coords[0][1] = rect->top; coords[0][2] = 0.0f; - coords[1][0] = rect->right; coords[1][1] = rect->top; coords[1][2] = 0.0f; - coords[2][0] = rect->left; coords[2][1] = rect->bottom; coords[2][2] = 0.0f; - coords[3][0] = rect->right; coords[3][1] = rect->bottom; coords[3][2] = 0.0f; + coords[0].x = rect->left; coords[0].y = rect->top; coords[0].z = 0.0f; + coords[1].x = rect->right; coords[1].y = rect->top; coords[1].z = 0.0f; + coords[2].x = rect->left; coords[2].y = rect->bottom; coords[2].z = 0.0f; + coords[3].x = rect->right; coords[3].y = rect->bottom; coords[3].z = 0.0f; break; case GL_TEXTURE_CUBE_MAP_POSITIVE_X: @@ -140,10 +140,10 @@ static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLs info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; cube_coords_float(rect, w, h, &f); - coords[0][0] = 1.0f; coords[0][1] = -f.t; coords[0][2] = -f.l; - coords[1][0] = 1.0f; coords[1][1] = -f.t; coords[1][2] = -f.r; - coords[2][0] = 1.0f; coords[2][1] = -f.b; coords[2][2] = -f.l; - coords[3][0] = 1.0f; coords[3][1] = -f.b; coords[3][2] = -f.r; + coords[0].x = 1.0f; coords[0].y = -f.t; coords[0].z = -f.l; + coords[1].x = 1.0f; coords[1].y = -f.t; coords[1].z = -f.r; + coords[2].x = 1.0f; coords[2].y = -f.b; coords[2].z = -f.l; + coords[3].x = 1.0f; coords[3].y = -f.b; coords[3].z = -f.r; break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: @@ -152,10 +152,10 @@ static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLs info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; cube_coords_float(rect, w, h, &f); - coords[0][0] = -1.0f; coords[0][1] = -f.t; coords[0][2] = f.l; - coords[1][0] = -1.0f; coords[1][1] = -f.t; coords[1][2] = f.r; - coords[2][0] = -1.0f; coords[2][1] = -f.b; coords[2][2] = f.l; - coords[3][0] = -1.0f; coords[3][1] = -f.b; coords[3][2] = f.r; + coords[0].x = -1.0f; coords[0].y = -f.t; coords[0].z = f.l; + coords[1].x = -1.0f; coords[1].y = -f.t; coords[1].z = f.r; + coords[2].x = -1.0f; coords[2].y = -f.b; coords[2].z = f.l; + coords[3].x = -1.0f; coords[3].y = -f.b; coords[3].z = f.r; break; case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: @@ -164,10 +164,10 @@ static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLs info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; cube_coords_float(rect, w, h, &f); - coords[0][0] = f.l; coords[0][1] = 1.0f; coords[0][2] = f.t; - coords[1][0] = f.r; coords[1][1] = 1.0f; coords[1][2] = f.t; - coords[2][0] = f.l; coords[2][1] = 1.0f; coords[2][2] = f.b; - coords[3][0] = f.r; coords[3][1] = 1.0f; coords[3][2] = f.b; + coords[0].x = f.l; coords[0].y = 1.0f; coords[0].z = f.t; + coords[1].x = f.r; coords[1].y = 1.0f; coords[1].z = f.t; + coords[2].x = f.l; coords[2].y = 1.0f; coords[2].z = f.b; + coords[3].x = f.r; coords[3].y = 1.0f; coords[3].z = f.b; break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: @@ -176,10 +176,10 @@ static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLs info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; cube_coords_float(rect, w, h, &f); - coords[0][0] = f.l; coords[0][1] = -1.0f; coords[0][2] = -f.t; - coords[1][0] = f.r; coords[1][1] = -1.0f; coords[1][2] = -f.t; - coords[2][0] = f.l; coords[2][1] = -1.0f; coords[2][2] = -f.b; - coords[3][0] = f.r; coords[3][1] = -1.0f; coords[3][2] = -f.b; + coords[0].x = f.l; coords[0].y = -1.0f; coords[0].z = -f.t; + coords[1].x = f.r; coords[1].y = -1.0f; coords[1].z = -f.t; + coords[2].x = f.l; coords[2].y = -1.0f; coords[2].z = -f.b; + coords[3].x = f.r; coords[3].y = -1.0f; coords[3].z = -f.b; break; case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: @@ -188,10 +188,10 @@ static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLs info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; cube_coords_float(rect, w, h, &f); - coords[0][0] = f.l; coords[0][1] = -f.t; coords[0][2] = 1.0f; - coords[1][0] = f.r; coords[1][1] = -f.t; coords[1][2] = 1.0f; - coords[2][0] = f.l; coords[2][1] = -f.b; coords[2][2] = 1.0f; - coords[3][0] = f.r; coords[3][1] = -f.b; coords[3][2] = 1.0f; + coords[0].x = f.l; coords[0].y = -f.t; coords[0].z = 1.0f; + coords[1].x = f.r; coords[1].y = -f.t; coords[1].z = 1.0f; + coords[2].x = f.l; coords[2].y = -f.b; coords[2].z = 1.0f; + coords[3].x = f.r; coords[3].y = -f.b; coords[3].z = 1.0f; break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: @@ -200,10 +200,10 @@ static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLs info->tex_type = WINED3D_GL_RES_TYPE_TEX_CUBE; cube_coords_float(rect, w, h, &f); - coords[0][0] = -f.l; coords[0][1] = -f.t; coords[0][2] = -1.0f; - coords[1][0] = -f.r; coords[1][1] = -f.t; coords[1][2] = -1.0f; - coords[2][0] = -f.l; coords[2][1] = -f.b; coords[2][2] = -1.0f; - coords[3][0] = -f.r; coords[3][1] = -f.b; coords[3][2] = -1.0f; + coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z = -1.0f; + coords[1].x = -f.r; coords[1].y = -f.t; coords[1].z = -1.0f; + coords[2].x = -f.l; coords[2].y = -f.b; coords[2].z = -1.0f; + coords[3].x = -f.r; coords[3].y = -f.b; coords[3].z = -1.0f; break; } } @@ -253,16 +253,16 @@ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3 /* Draw a quad */ gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[0]); + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[0].x); gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->top); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[1]); + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[1].x); gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->top); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[2]); + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[2].x); gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->bottom); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[3]); + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[3].x); gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->bottom); gl_info->gl_ops.gl.p_glEnd(); @@ -2561,13 +2561,13 @@ static void surface_depth_blt(const struct wined3d_surface *surface, struct wine gl_info, info.tex_type, &surface->ds_current_size); gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[0]); + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[0].x); gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[1]); + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[1].x); gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[2]); + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[2].x); gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f); - gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[3]); + gl_info->gl_ops.gl.p_glTexCoord3fv(&info.texcoords[3].x); gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f); gl_info->gl_ops.gl.p_glEnd(); -- 2.7.3 From sebastian at fds-team.de Thu Oct 13 22:58:17 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Fri, 14 Oct 2016 05:58:17 +0200 Subject: wmic: Improve cmd line parser and add support for path command. Message-ID: <5422882e-8de4-89ee-90f3-222f1757a6ae@fds-team.de> From: Michael Müller Signed-off-by: Michael Müller Signed-off-by: Sebastian Lackner --- This allows to use more complicated command line arguments like "wmic path Win32_Processor get name". programs/wmic/main.c | 71 +++++++++++++++++++++++++++++++++++++++++--------- programs/wmic/wmic.h | 1 programs/wmic/wmic.rc | 1 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/programs/wmic/main.c b/programs/wmic/main.c index 5aee4c1..ddd2aec 100644 --- a/programs/wmic/main.c +++ b/programs/wmic/main.c @@ -162,7 +162,7 @@ static int output_message( int msg ) return output_string( fmtW, buffer ); } -static int query_prop( const WCHAR *alias, const WCHAR *propname ) +static int query_prop( const WCHAR *class, const WCHAR *propname ) { static const WCHAR select_allW[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0}; static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0}; @@ -175,18 +175,12 @@ static int query_prop( const WCHAR *alias, const WCHAR *propname ) IEnumWbemClassObject *result = NULL; LONG flags = WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY; BSTR path = NULL, wql = NULL, query = NULL; - const WCHAR *class; WCHAR *prop = NULL; BOOL first = TRUE; int len, ret = -1; - WINE_TRACE("%s, %s\n", debugstr_w(alias), debugstr_w(propname)); + WINE_TRACE("%s, %s\n", debugstr_w(class), debugstr_w(propname)); - if (!(class = find_class( alias ))) - { - output_message( STRING_ALIAS_NOT_FOUND ); - return -1; - } CoInitialize( NULL ); CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL ); @@ -253,11 +247,64 @@ done: int wmain(int argc, WCHAR *argv[]) { static const WCHAR getW[] = {'g','e','t',0}; + static const WCHAR quitW[] = {'q','u','i','t',0}; + static const WCHAR exitW[] = {'e','x','i','t',0}; + static const WCHAR pathW[] = {'p','a','t','h',0}; + static const WCHAR classW[] = {'c','l','a','s','s',0}; + static const WCHAR contextW[] = {'c','o','n','t','e','x','t',0}; + const WCHAR *class, *value; + int i; + + for (i = 1; i < argc && argv[i][0] == '/'; i++) + WINE_FIXME( "command line switch %s not supported\n", debugstr_w(argv[i]) ); + + if (i >= argc) + goto not_supported; + + if (!strcmpiW( argv[i], quitW ) || + !strcmpiW( argv[i], exitW )) + { + return 0; + } - if (argc != 4 || strcmpiW( argv[2], getW )) + if (!strcmpiW( argv[i], classW) || + !strcmpiW( argv[i], contextW )) { - output_message( STRING_CMDLINE_NOT_SUPPORTED ); - return -1; + WINE_FIXME( "command %s not supported\n", debugstr_w(argv[i]) ); + goto not_supported; + } + + if (!strcmpiW( argv[i], pathW )) + { + if (++i >= argc) + { + output_message( STRING_INVALID_PATH ); + return 1; + } + class = argv[i]; } - return query_prop( argv[1], argv[3] ); + else + { + class = find_class( argv[i] ); + if (!class) + { + output_message( STRING_ALIAS_NOT_FOUND ); + return 1; + } + } + + if (++i >= argc) + goto not_supported; + + if (!strcmpiW( argv[i], getW )) + { + if (++i >= argc) + goto not_supported; + value = argv[i]; + return query_prop( class, value ); + } + +not_supported: + output_message( STRING_CMDLINE_NOT_SUPPORTED ); + return 1; } diff --git a/programs/wmic/wmic.h b/programs/wmic/wmic.h index ee56d8e..2727270 100644 --- a/programs/wmic/wmic.h +++ b/programs/wmic/wmic.h @@ -21,3 +21,4 @@ #define STRING_CMDLINE_NOT_SUPPORTED 101 #define STRING_ALIAS_NOT_FOUND 102 #define STRING_INVALID_QUERY 103 +#define STRING_INVALID_PATH 104 diff --git a/programs/wmic/wmic.rc b/programs/wmic/wmic.rc index 54384fb..0789ef3 100644 --- a/programs/wmic/wmic.rc +++ b/programs/wmic/wmic.rc @@ -27,4 +27,5 @@ STRINGTABLE STRING_CMDLINE_NOT_SUPPORTED, "Error: Command line not supported\n" STRING_ALIAS_NOT_FOUND, "Error: Alias not found\n" STRING_INVALID_QUERY, "Error: Invalid query\n" + STRING_INVALID_PATH, "Error: Invalid syntax for PATH\n" } -- 2.9.0 From aric at codeweavers.com Thu Oct 13 23:25:21 2016 From: aric at codeweavers.com (Aric Stewart) Date: Fri, 14 Oct 2016 06:25:21 +0200 Subject: [PATCH v3] winehid: Implement handing internal ioctls Message-ID: Mostly by passing them to the bus driver where platform specific actions happen v2: Suggestion from Sebastian Lackner v3: Rebased and a few more suggestions from Sebastian Lackner Signed-off-by: Aric Stewart --- dlls/winehid.sys/main.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: v3-0001-winehid-Implement-handing-internal-ioctls.txt Type: text/x-patch Size: 2296 bytes Desc: not available URL: From sebastian at fds-team.de Thu Oct 13 23:40:59 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Fri, 14 Oct 2016 06:40:59 +0200 Subject: wine.inf: Add WineHID to the CriticalDeviceDatabase. Message-ID: <2ea2b854-d480-cb25-aec4-e58a134fb85e@fds-team.de> From: Aric Stewart Signed-off-by: Sebastian Lackner --- @ Aric: Do you think it is fine to add that now, or should we wait a bit more? My feeling is that it will be difficult to test the functionality when users have to add this key manually (in addition to "net start WineBus"). I'm aware that a lot of things do not work yet (current Wine git seems to be stuck in an endless flood of FIXMEs). loader/wine.inf.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/loader/wine.inf.in b/loader/wine.inf.in index fcf9c4a..991857e 100644 --- a/loader/wine.inf.in +++ b/loader/wine.inf.in @@ -35,6 +35,7 @@ AddReg=\ Classes,\ ContentIndex,\ ControlClass,\ + CriticalDevice,\ CurrentVersion,\ Debugger,\ DirectX,\ @@ -59,6 +60,7 @@ AddReg=\ Classes,\ ContentIndex,\ ControlClass,\ + CriticalDevice,\ CurrentVersion,\ Debugger,\ DirectX,\ @@ -85,6 +87,7 @@ AddReg=\ Classes,\ ContentIndex,\ ControlClass,\ + CriticalDevice,\ CurrentVersion,\ CurrentVersionWow64,\ Debugger,\ @@ -466,6 +469,9 @@ HKLM,System\CurrentControlSet\Control\Class\{6bdd1fc6-810f-11d0-bec7-08002be2092 HKLM,System\CurrentControlSet\Control\Class\{745a17a0-74d3-11d0-b6fe-00a0c90f57da},,,"Human Interface Devices" HKLM,System\CurrentControlSet\Control\Class\{745a17a0-74d3-11d0-b6fe-00a0c90f57da},"Class",,"HIDClass" +[CriticalDevice] +HKLM,System\CurrentControlSet\Control\CriticalDeviceDatabase\HIDRAW,"Service",,"WineHID" + [CurrentVersion] HKCU,%CurrentVersion%\Run,,16 HKLM,%CurrentVersion%,"CommonFilesDir",,"%16427%" -- 2.9.0 From aric at codeweavers.com Thu Oct 13 23:43:35 2016 From: aric at codeweavers.com (Aric Stewart) Date: Fri, 14 Oct 2016 06:43:35 +0200 Subject: wine.inf: Add WineHID to the CriticalDeviceDatabase. In-Reply-To: <2ea2b854-d480-cb25-aec4-e58a134fb85e@fds-team.de> References: <2ea2b854-d480-cb25-aec4-e58a134fb85e@fds-team.de> Message-ID: <7ef06d2a-3eac-06fc-e15d-cb808d38f276@codeweavers.com> Signed-off-by: Aric Stewart I was just working this patch myself. -aric On 10/14/16 6:40 AM, Sebastian Lackner wrote: > From: Aric Stewart > > Signed-off-by: Sebastian Lackner > --- > > @ Aric: Do you think it is fine to add that now, or should we wait a bit more? > My feeling is that it will be difficult to test the functionality when users > have to add this key manually (in addition to "net start WineBus"). I'm > aware that a lot of things do not work yet (current Wine git seems to be > stuck in an endless flood of FIXMEs). > > loader/wine.inf.in | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/loader/wine.inf.in b/loader/wine.inf.in > index fcf9c4a..991857e 100644 > --- a/loader/wine.inf.in > +++ b/loader/wine.inf.in > @@ -35,6 +35,7 @@ AddReg=\ > Classes,\ > ContentIndex,\ > ControlClass,\ > + CriticalDevice,\ > CurrentVersion,\ > Debugger,\ > DirectX,\ > @@ -59,6 +60,7 @@ AddReg=\ > Classes,\ > ContentIndex,\ > ControlClass,\ > + CriticalDevice,\ > CurrentVersion,\ > Debugger,\ > DirectX,\ > @@ -85,6 +87,7 @@ AddReg=\ > Classes,\ > ContentIndex,\ > ControlClass,\ > + CriticalDevice,\ > CurrentVersion,\ > CurrentVersionWow64,\ > Debugger,\ > @@ -466,6 +469,9 @@ HKLM,System\CurrentControlSet\Control\Class\{6bdd1fc6-810f-11d0-bec7-08002be2092 > HKLM,System\CurrentControlSet\Control\Class\{745a17a0-74d3-11d0-b6fe-00a0c90f57da},,,"Human Interface Devices" > HKLM,System\CurrentControlSet\Control\Class\{745a17a0-74d3-11d0-b6fe-00a0c90f57da},"Class",,"HIDClass" > > +[CriticalDevice] > +HKLM,System\CurrentControlSet\Control\CriticalDeviceDatabase\HIDRAW,"Service",,"WineHID" > + > [CurrentVersion] > HKCU,%CurrentVersion%\Run,,16 > HKLM,%CurrentVersion%,"CommonFilesDir",,"%16427%" > From aric at codeweavers.com Thu Oct 13 23:44:53 2016 From: aric at codeweavers.com (Aric Stewart) Date: Fri, 14 Oct 2016 06:44:53 +0200 Subject: [PATCH v4] winehid: Implement handing internal ioctls Message-ID: <1ad9d114-4aea-6c96-89a1-e88de3b3c567@codeweavers.com> Mostly by passing them to the bus driver where platform specific actions happen v2: Suggestion from Sebastian Lackner v3: Rebased and a few more suggestions from Sebastian Lackner v4: Add missing ntoskrnl dependency Signed-off-by: Aric Stewart --- dlls/winehid.sys/Makefile.in | 2 +- dlls/winehid.sys/main.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: v4-0001-winehid-Implement-handing-internal-ioctls.txt Type: text/x-patch Size: 2617 bytes Desc: not available URL: From sebastian at fds-team.de Thu Oct 13 23:46:12 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Fri, 14 Oct 2016 06:46:12 +0200 Subject: ntoskrnl.exe: Do not abuse UserEvent to store event handle. Message-ID: Signed-off-by: Sebastian Lackner --- dlls/ntoskrnl.exe/ntoskrnl.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 974f946..428e700 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -2883,7 +2883,8 @@ done: static NTSTATUS WINAPI internal_complete( DEVICE_OBJECT *device, IRP *irp, void *context ) { - SetEvent( irp->UserEvent ); + HANDLE event = context; + SetEvent( event ); return STATUS_MORE_PROCESSING_REQUIRED; } @@ -2891,15 +2892,11 @@ static NTSTATUS WINAPI internal_complete( DEVICE_OBJECT *device, IRP *irp, void static NTSTATUS send_device_irp( DEVICE_OBJECT *device, IRP *irp, ULONG_PTR *info ) { NTSTATUS status; - IO_STACK_LOCATION *irpsp; HANDLE event = CreateEventA( NULL, FALSE, FALSE, NULL ); DEVICE_OBJECT *toplevel_device; - irp->UserEvent = event; irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED; - irpsp = IoGetNextIrpStackLocation( irp ); - irpsp->CompletionRoutine = internal_complete; - irpsp->Control = SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR | SL_INVOKE_ON_CANCEL; + IoSetCompletionRoutine( irp, internal_complete, event, TRUE, TRUE, TRUE ); toplevel_device = IoGetAttachedDeviceReference( device ); status = IoCallDriver( toplevel_device, irp ); -- 2.9.0 From sebastian at fds-team.de Fri Oct 14 01:12:46 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Fri, 14 Oct 2016 08:12:46 +0200 Subject: winehid.sys: Implement handing internal ioctls. (v5) Message-ID: <9f6d7b1f-4e1f-00b2-b2cd-4527435cd594@fds-team.de> From: Aric Stewart Signed-off-by: Aric Stewart Signed-off-by: Sebastian Lackner --- Changes in v5: * Use NONAMELESSUNION to avoid possible compile issues on unusual platforms. (Sorry if this was a misunderstanding, I was only removing it from patch 1 because it was not necessary for the stub driver yet.) * Minor style improvements (for example, put the comma in the FIXME on the previous line, so that the style is the same as in winebus). dlls/winehid.sys/Makefile.in | 2 +- dlls/winehid.sys/main.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/dlls/winehid.sys/Makefile.in b/dlls/winehid.sys/Makefile.in index ad7881e..8db0f0e 100644 --- a/dlls/winehid.sys/Makefile.in +++ b/dlls/winehid.sys/Makefile.in @@ -1,5 +1,5 @@ MODULE = winehid.sys -IMPORTS = hidclass +IMPORTS = hidclass ntoskrnl EXTRADLLFLAGS = -Wb,--subsystem,native C_SRCS = \ diff --git a/dlls/winehid.sys/main.c b/dlls/winehid.sys/main.c index cdef3c5..42e2e48 100644 --- a/dlls/winehid.sys/main.c +++ b/dlls/winehid.sys/main.c @@ -20,17 +20,58 @@ #include +#define NONAMELESSUNION + #include "ntstatus.h" #define WIN32_NO_STATUS #include "windef.h" #include "winbase.h" #include "winternl.h" +#include "winioctl.h" #include "ddk/wdm.h" #include "ddk/hidport.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(hid); +static NTSTATUS WINAPI internal_ioctl(DEVICE_OBJECT *device, IRP *irp) +{ + NTSTATUS status = irp->IoStatus.u.Status; + IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); + + switch (irpsp->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_GET_PHYSICAL_DESCRIPTOR: + case IOCTL_HID_ACTIVATE_DEVICE: + case IOCTL_HID_DEACTIVATE_DEVICE: + case IOCTL_HID_GET_INDEXED_STRING: + case IOCTL_HID_GET_DEVICE_ATTRIBUTES: + case IOCTL_HID_GET_DEVICE_DESCRIPTOR: + case IOCTL_HID_GET_REPORT_DESCRIPTOR: + case IOCTL_HID_GET_STRING: + case IOCTL_HID_GET_INPUT_REPORT: + case IOCTL_HID_READ_REPORT: + case IOCTL_HID_SET_OUTPUT_REPORT: + case IOCTL_HID_WRITE_REPORT: + case IOCTL_HID_GET_FEATURE: + case IOCTL_HID_SET_FEATURE: + { + /* All these are handled by the lower level driver */ + IoSkipCurrentIrpStackLocation(irp); + return IoCallDriver(((HID_DEVICE_EXTENSION *)device->DeviceExtension)->NextDeviceObject, irp); + } + default: + { + ULONG code = irpsp->Parameters.DeviceIoControl.IoControlCode; + FIXME("Unsupported ioctl %x (device=%x access=%x func=%x method=%x)\n", + code, code >> 16, (code >> 14) & 3, (code >> 2) & 0xfff, code & 3); + break; + } + } + IoCompleteRequest(irp, IO_NO_INCREMENT); + return status; +} + static NTSTATUS WINAPI add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *device) { TRACE("(%p, %p)\n", driver, device); @@ -43,6 +84,7 @@ NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path) TRACE("(%p, %s)\n", driver, debugstr_w(path->Buffer)); + driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = internal_ioctl; driver->DriverExtension->AddDevice = add_device; memset(®istration, 0, sizeof(registration)); -- 2.9.0 From donat at enikeev.net Fri Oct 14 01:37:08 2016 From: donat at enikeev.net (Donat Enikeev) Date: Fri, 14 Oct 2016 09:37:08 +0300 Subject: [v2 1/2] crypt32: tests for Cert(Un)registerSystemStore Message-ID: <1476427029-18795-1-git-send-email-donat@enikeev.net> Supercedes https://source.winehq.org/patches/data/127020 v2: 1. Fix crashes on Win864 in legacy test by removing CertFreeCertificateContext(cert3) in 2 places. It should be removed as there are CertDeleteCertificateFromStore(cert3) few lines before: per MSDN "The CertDeleteCertificateFromStore function always frees pCertContext by calling the CertFreeCertificateContext function, even if an error is encountered", however seems only Win864 can't tolerate that call. 2. Style, readability and more sophisticated test cases Signed-off-by: Donat Enikeev --- dlls/crypt32/tests/store.c | 92 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 4 deletions(-) diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c index 4483936..e811fbe 100644 --- a/dlls/crypt32/tests/store.c +++ b/dlls/crypt32/tests/store.c @@ -123,6 +123,8 @@ static BOOL (WINAPI *pCertGetStoreProperty)(HCERTSTORE,DWORD,void*,DWORD*); static void (WINAPI *pCertRemoveStoreFromCollection)(HCERTSTORE,HCERTSTORE); static BOOL (WINAPI *pCertSetStoreProperty)(HCERTSTORE,DWORD,DWORD,const void*); static BOOL (WINAPI *pCertAddCertificateLinkToStore)(HCERTSTORE,PCCERT_CONTEXT,DWORD,PCCERT_CONTEXT*); +static BOOL (WINAPI *pCertRegisterSystemStore)(const void*,DWORD,void*,void*); +static BOOL (WINAPI *pCertUnregisterSystemStore)(const void*,DWORD); #define test_store_is_empty(store) _test_store_is_empty(__LINE__,store) static void _test_store_is_empty(unsigned line, HCERTSTORE store) @@ -1868,6 +1870,88 @@ static void testCertOpenSystemStore(void) RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW); } +static const struct +{ + DWORD cert_store; + BOOL expected; + BOOL todo; +} reg_system_store_test_data[] = { + { CERT_SYSTEM_STORE_CURRENT_USER, TRUE, 0}, + /* Following tests could require administrator privileges and thus could be skipped */ + { CERT_SYSTEM_STORE_CURRENT_SERVICE, TRUE, 1}, + { CERT_SYSTEM_STORE_LOCAL_MACHINE, TRUE, 0}, + { CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, TRUE, 0}, + { CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, TRUE, 0}, + { CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, TRUE, 1} +}; + +static void testCertRegisterSystemStore(void) +{ + BOOL ret, cur_flag; + DWORD err = 0; + HCERTSTORE hstore; + static const WCHAR WineTestW[] = {'W','i','n','e','T','e','s','t',0}; + const CERT_CONTEXT *cert, *cert2; + unsigned int i; + + if (!pCertRegisterSystemStore || !pCertUnregisterSystemStore) + { + win_skip("CertRegisterSystemStore() or CertUnregisterSystemStore() is not available\n"); + return; + } + + for (i = 0; i < sizeof(reg_system_store_test_data) / sizeof(reg_system_store_test_data[0]); i++) { + cur_flag = reg_system_store_test_data[i].cert_store; + ret = pCertRegisterSystemStore(WineTestW, cur_flag, NULL, NULL); + if (!ret) + { + err = GetLastError(); + if (err == ERROR_ACCESS_DENIED) + { + win_skip("Insufficient privileges for the flag %08x test\n", cur_flag); + continue; + } + } + todo_wine_if (reg_system_store_test_data[i].todo) + ok (ret == reg_system_store_test_data[i].expected, + "Store registration (dwFlags=%08x) failed, last error %x\n", cur_flag, err); + if (!ret) + { + skip("Nothing to test without registered store at %08x\n", cur_flag); + continue; + } + + hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, CERT_STORE_OPEN_EXISTING_FLAG | cur_flag, WineTestW); + ok (hstore != NULL, "Opening just registered store at %08x failed, last error %x\n", cur_flag, GetLastError()); + + cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); + ok (cert != NULL, "Failed creating cert at %08x, last error: %x\n", cur_flag, GetLastError()); + if (cert) + { + ret = CertAddCertificateContextToStore(hstore, cert, CERT_STORE_ADD_NEW, NULL); + ok (ret, "Failed to add cert at %08x, last error: %x\n", cur_flag, GetLastError()); + + cert2 = CertEnumCertificatesInStore(hstore, NULL); + ok (cert2 != NULL && cert2->cbCertEncoded == cert->cbCertEncoded, + "Unexpected cert encoded size at %08x, last error: %x\n", cur_flag, GetLastError()); + + ret = CertDeleteCertificateFromStore(cert2); + ok (ret, "Failed to delete certificate from the new store at %08x, last error: %x\n", cur_flag, GetLastError()); + + CertFreeCertificateContext(cert); + } + + ret = CertCloseStore(hstore, 0); + ok (ret, "CertCloseStore failed at %08x, last error %x", cur_flag, GetLastError()); + + ret = pCertUnregisterSystemStore(WineTestW, cur_flag ); + todo_wine_if (reg_system_store_test_data[i].todo) + ok( ret == reg_system_store_test_data[i].expected, + "Unregistering failed at %08x, last error %d\n", cur_flag, GetLastError()); + } + +} + struct EnumSystemStoreInfo { BOOL goOn; @@ -2587,8 +2671,6 @@ static void testEmptyStore(void) ok(res, "CertDeleteCertificateContextFromStore failed\n"); ok(cert3->hCertStore == cert->hCertStore, "Unexpected hCertStore\n"); - CertFreeCertificateContext(cert3); - store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); ok(store != NULL, "CertOpenStore failed\n"); @@ -2601,8 +2683,6 @@ static void testEmptyStore(void) ok(res, "CertDeleteCertificateContextFromStore failed\n"); ok(cert3->hCertStore == store, "Unexpected hCertStore\n"); - CertFreeCertificateContext(cert3); - CertCloseStore(store, 0); res = CertCloseStore(cert->hCertStore, CERT_CLOSE_STORE_CHECK_FLAG); @@ -2808,6 +2888,8 @@ START_TEST(store) pCertRemoveStoreFromCollection = (void*)GetProcAddress(hdll, "CertRemoveStoreFromCollection"); pCertSetStoreProperty = (void*)GetProcAddress(hdll, "CertSetStoreProperty"); pCertAddCertificateLinkToStore = (void*)GetProcAddress(hdll, "CertAddCertificateLinkToStore"); + pCertRegisterSystemStore = (void*)GetProcAddress(hdll, "CertRegisterSystemStore"); + pCertUnregisterSystemStore = (void*)GetProcAddress(hdll, "CertUnregisterSystemStore"); /* various combinations of CertOpenStore */ testMemStore(); @@ -2821,6 +2903,8 @@ START_TEST(store) testSerializedStore(); testCloseStore(); + testCertRegisterSystemStore(); + testCertOpenSystemStore(); testCertEnumSystemStore(); testStoreProperty(); -- 2.7.4 From donat at enikeev.net Fri Oct 14 01:37:09 2016 From: donat at enikeev.net (Donat Enikeev) Date: Fri, 14 Oct 2016 09:37:09 +0300 Subject: [v2 2/2] crypt32: Cert(Un)RegisterSystemStore semi-stubs In-Reply-To: <1476427029-18795-1-git-send-email-donat@enikeev.net> References: <1476427029-18795-1-git-send-email-donat@enikeev.net> Message-ID: <1476427029-18795-2-git-send-email-donat@enikeev.net> Fixes https://bugs.winehq.org/show_bug.cgi?id=40314 Supercedes https://source.winehq.org/patches/data/127020 v2: implementation via re-using existing functions Signed-off-by: Donat Enikeev --- dlls/crypt32/crypt32.spec | 2 ++ dlls/crypt32/store.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec index 0d2a477..b5ce48c 100644 --- a/dlls/crypt32/crypt32.spec +++ b/dlls/crypt32/crypt32.spec @@ -78,6 +78,7 @@ @ stdcall CertRDNValueToStrA(long ptr ptr long) @ stdcall CertRDNValueToStrW(long ptr ptr long) @ stdcall CertRegisterPhysicalStore(ptr long wstr ptr ptr) +@ stdcall CertRegisterSystemStore(ptr long ptr ptr) @ stdcall CertRemoveEnhancedKeyUsageIdentifier(ptr str) @ stdcall CertRemoveStoreFromCollection(ptr ptr) @ stdcall CertSaveStore(ptr long long long ptr long) @@ -190,6 +191,7 @@ @ stdcall CryptUnprotectMemory(ptr long long) @ stdcall CryptUnregisterDefaultOIDFunction(long str wstr) @ stdcall CryptUnregisterOIDFunction(long str str) +@ stdcall CertUnregisterSystemStore(ptr long) @ stub CryptUnregisterOIDInfo @ stdcall CryptVerifyCertificateSignature(long long ptr long ptr) @ stdcall CryptVerifyCertificateSignatureEx(long long long ptr long ptr long ptr) diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c index d5d7443..356712b 100644 --- a/dlls/crypt32/store.c +++ b/dlls/crypt32/store.c @@ -1390,6 +1390,51 @@ BOOL WINAPI CertRegisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags, return FALSE; } +BOOL WINAPI CertRegisterSystemStore(const void *pvSystemStore, DWORD dwFlags, + PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved) +{ + HCERTSTORE hstore; + + if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG ) + { + FIXME("(%p, %08x, %p, %p): flag not supported\n", pvSystemStore, dwFlags, pStoreInfo, pvReserved); + return FALSE; + } + + TRACE("(%s, %08x, %p, %p)\n", debugstr_w(pvSystemStore), dwFlags, pStoreInfo, pvReserved); + + hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, dwFlags, pvSystemStore); + if (hstore) + { + CertCloseStore(hstore, 0); + return TRUE; + } + + return FALSE; +} + +BOOL WINAPI CertUnregisterSystemStore(void *pvSystemStore, DWORD dwFlags) +{ + HCERTSTORE hstore; + + if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG) + { + FIXME("(%p, %08x): flag not supported\n", pvSystemStore, dwFlags); + return FALSE; + } + TRACE("(%s, %08x)\n", debugstr_w(pvSystemStore), dwFlags); + + hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, dwFlags | CERT_STORE_OPEN_EXISTING_FLAG, pvSystemStore); + if (hstore == NULL) + return FALSE; + + hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, dwFlags | CERT_STORE_DELETE_FLAG, pvSystemStore); + if (hstore == NULL && GetLastError() == 0) + return TRUE; + + return FALSE; +} + static void EmptyStore_addref(WINECRYPT_CERTSTORE *store) { TRACE("(%p)\n", store); -- 2.7.4 From aric at codeweavers.com Fri Oct 14 01:54:33 2016 From: aric at codeweavers.com (aric at codeweavers.com) Date: Fri, 14 Oct 2016 08:54:33 +0200 Subject: [PATCH v3 1/2] winebus.sys: Add a strdupAtoW implementation. Message-ID: <6ed5dfe3-54f1-5ae4-0397-cbccc8013c66@codeweavers.com> Signed-off-by: Aric Stewart From: Sebastian Lackner --- dlls/winebus.sys/bus_udev.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: v3-0002-winebus.sys-Add-a-strdupAtoW-implementation.txt Type: text/x-patch Size: 1564 bytes Desc: not available URL: From aric at codeweavers.com Fri Oct 14 01:54:52 2016 From: aric at codeweavers.com (Aric Stewart) Date: Fri, 14 Oct 2016 08:54:52 +0200 Subject: [PATCH v3 2/2] winebus.sys: Implement IOCTL_HID_GET_STRING for hidraw Message-ID: v2: Suggestion from Sebastian Lackner v3: Further suggestions from Sebastian Lackner Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_udev.c | 73 +++++++++++++++++++++++++++++++++++++++++++++ dlls/winebus.sys/main.c | 11 +++++++ 3 files changed, 85 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: v3-0003-winebus.sys-Implement-IOCTL_HID_GET_STRING-for-hidr.txt Type: text/x-patch Size: 4367 bytes Desc: not available URL: From aric at codeweavers.com Fri Oct 14 01:56:05 2016 From: aric at codeweavers.com (Aric Stewart) Date: Fri, 14 Oct 2016 08:56:05 +0200 Subject: winehid.sys: Implement handing internal ioctls. (v5) In-Reply-To: <9f6d7b1f-4e1f-00b2-b2cd-4527435cd594@fds-team.de> References: <9f6d7b1f-4e1f-00b2-b2cd-4527435cd594@fds-team.de> Message-ID: <15f62150-d99a-a4bf-c5eb-e57afae5a24d@codeweavers.com> Signed-off-by: Aric Stewart On 10/14/16 8:12 AM, Sebastian Lackner wrote: > From: Aric Stewart > > Signed-off-by: Aric Stewart > Signed-off-by: Sebastian Lackner > --- > > Changes in v5: > * Use NONAMELESSUNION to avoid possible compile issues on unusual platforms. > (Sorry if this was a misunderstanding, I was only removing it from patch 1 > because it was not necessary for the stub driver yet.) > * Minor style improvements (for example, put the comma in the FIXME on the > previous line, so that the style is the same as in winebus). > > dlls/winehid.sys/Makefile.in | 2 +- > dlls/winehid.sys/main.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 43 insertions(+), 1 deletion(-) > > diff --git a/dlls/winehid.sys/Makefile.in b/dlls/winehid.sys/Makefile.in > index ad7881e..8db0f0e 100644 > --- a/dlls/winehid.sys/Makefile.in > +++ b/dlls/winehid.sys/Makefile.in > @@ -1,5 +1,5 @@ > MODULE = winehid.sys > -IMPORTS = hidclass > +IMPORTS = hidclass ntoskrnl > EXTRADLLFLAGS = -Wb,--subsystem,native > > C_SRCS = \ > diff --git a/dlls/winehid.sys/main.c b/dlls/winehid.sys/main.c > index cdef3c5..42e2e48 100644 > --- a/dlls/winehid.sys/main.c > +++ b/dlls/winehid.sys/main.c > @@ -20,17 +20,58 @@ > > #include > > +#define NONAMELESSUNION > + > #include "ntstatus.h" > #define WIN32_NO_STATUS > #include "windef.h" > #include "winbase.h" > #include "winternl.h" > +#include "winioctl.h" > #include "ddk/wdm.h" > #include "ddk/hidport.h" > #include "wine/debug.h" > > WINE_DEFAULT_DEBUG_CHANNEL(hid); > > +static NTSTATUS WINAPI internal_ioctl(DEVICE_OBJECT *device, IRP *irp) > +{ > + NTSTATUS status = irp->IoStatus.u.Status; > + IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); > + > + switch (irpsp->Parameters.DeviceIoControl.IoControlCode) > + { > + case IOCTL_GET_PHYSICAL_DESCRIPTOR: > + case IOCTL_HID_ACTIVATE_DEVICE: > + case IOCTL_HID_DEACTIVATE_DEVICE: > + case IOCTL_HID_GET_INDEXED_STRING: > + case IOCTL_HID_GET_DEVICE_ATTRIBUTES: > + case IOCTL_HID_GET_DEVICE_DESCRIPTOR: > + case IOCTL_HID_GET_REPORT_DESCRIPTOR: > + case IOCTL_HID_GET_STRING: > + case IOCTL_HID_GET_INPUT_REPORT: > + case IOCTL_HID_READ_REPORT: > + case IOCTL_HID_SET_OUTPUT_REPORT: > + case IOCTL_HID_WRITE_REPORT: > + case IOCTL_HID_GET_FEATURE: > + case IOCTL_HID_SET_FEATURE: > + { > + /* All these are handled by the lower level driver */ > + IoSkipCurrentIrpStackLocation(irp); > + return IoCallDriver(((HID_DEVICE_EXTENSION *)device->DeviceExtension)->NextDeviceObject, irp); > + } > + default: > + { > + ULONG code = irpsp->Parameters.DeviceIoControl.IoControlCode; > + FIXME("Unsupported ioctl %x (device=%x access=%x func=%x method=%x)\n", > + code, code >> 16, (code >> 14) & 3, (code >> 2) & 0xfff, code & 3); > + break; > + } > + } > + IoCompleteRequest(irp, IO_NO_INCREMENT); > + return status; > +} > + > static NTSTATUS WINAPI add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *device) > { > TRACE("(%p, %p)\n", driver, device); > @@ -43,6 +84,7 @@ NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path) > > TRACE("(%p, %s)\n", driver, debugstr_w(path->Buffer)); > > + driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = internal_ioctl; > driver->DriverExtension->AddDevice = add_device; > > memset(®istration, 0, sizeof(registration)); > From hans at codeweavers.com Fri Oct 14 02:45:27 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Fri, 14 Oct 2016 09:45:27 +0200 Subject: wmic: Improve cmd line parser and add support for path command. In-Reply-To: <5422882e-8de4-89ee-90f3-222f1757a6ae@fds-team.de> References: <5422882e-8de4-89ee-90f3-222f1757a6ae@fds-team.de> Message-ID: <1476431127.6573.287.camel@codeweavers.com> Signed-off-by: Hans Leidekker From sebastian at fds-team.de Fri Oct 14 02:59:14 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Fri, 14 Oct 2016 09:59:14 +0200 Subject: [PATCH v3 1/2] winebus.sys: Add a strdupAtoW implementation. In-Reply-To: <6ed5dfe3-54f1-5ae4-0397-cbccc8013c66@codeweavers.com> References: <6ed5dfe3-54f1-5ae4-0397-cbccc8013c66@codeweavers.com> Message-ID: <1f2dde00-1a05-3952-db08-0e19b66127c6@fds-team.de> On 14.10.2016 08:54, aric at codeweavers.com wrote: > Signed-off-by: Aric Stewart > > From: Sebastian Lackner > --- > dlls/winebus.sys/bus_udev.c | 18 ++++++++++++------ > 1 file changed, 12 insertions(+), 6 deletions(-) > > > > > @Aric: Its better to have the From: header should be directly at the beginning, otherwise "git am" does not recognize it automatically. Signed-off-by: Sebastian Lackner From sebastian at fds-team.de Fri Oct 14 02:59:59 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Fri, 14 Oct 2016 09:59:59 +0200 Subject: [PATCH v3 2/2] winebus.sys: Implement IOCTL_HID_GET_STRING for hidraw In-Reply-To: References: Message-ID: <3ac1e705-5cd3-aa67-acc8-412194730357@fds-team.de> On 14.10.2016 08:54, Aric Stewart wrote: > > v2: Suggestion from Sebastian Lackner > v3: Further suggestions from Sebastian Lackner > Signed-off-by: Aric Stewart > --- > dlls/winebus.sys/bus.h | 1 + > dlls/winebus.sys/bus_udev.c | 73 +++++++++++++++++++++++++++++++++++++++++++++ > dlls/winebus.sys/main.c | 11 +++++++ > 3 files changed, 85 insertions(+) > Signed-off-by: Sebastian Lackner From huw at codeweavers.com Fri Oct 14 04:05:02 2016 From: huw at codeweavers.com (Huw Davies) Date: Fri, 14 Oct 2016 10:05:02 +0100 Subject: [PATCH 1/6] riched20: Initialize the remaining CHARFORMAT2 members. Message-ID: <1476435907-28859-1-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/para.c | 6 ++++-- dlls/riched20/tests/editor.c | 17 +++++++++++++++++ dlls/riched20/tests/richole.c | 1 - 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index d94e213..f050b2e 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -52,11 +52,12 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor) GetObjectW(hf, sizeof(LOGFONTW), &lf); ZeroMemory(&cf, sizeof(cf)); cf.cbSize = sizeof(cf); - cf.dwMask = CFM_BACKCOLOR|CFM_COLOR|CFM_FACE|CFM_SIZE|CFM_CHARSET; + cf.dwMask = CFM_ANIMATION|CFM_BACKCOLOR|CFM_CHARSET|CFM_COLOR|CFM_FACE|CFM_KERNING|CFM_LCID|CFM_OFFSET; + cf.dwMask |= CFM_REVAUTHOR|CFM_SIZE|CFM_SPACING|CFM_STYLE|CFM_UNDERLINETYPE|CFM_WEIGHT; cf.dwMask |= CFM_ALLCAPS|CFM_BOLD|CFM_DISABLED|CFM_EMBOSS|CFM_HIDDEN; cf.dwMask |= CFM_IMPRINT|CFM_ITALIC|CFM_LINK|CFM_OUTLINE|CFM_PROTECTED; cf.dwMask |= CFM_REVISED|CFM_SHADOW|CFM_SMALLCAPS|CFM_STRIKEOUT; - cf.dwMask |= CFM_SUBSCRIPT|CFM_UNDERLINETYPE|CFM_WEIGHT; + cf.dwMask |= CFM_SUBSCRIPT|CFM_UNDERLINE; cf.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR; lstrcpyW(cf.szFaceName, lf.lfFaceName); @@ -69,6 +70,7 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor) if (lf.lfStrikeOut) cf.dwEffects |= CFE_STRIKEOUT; cf.bPitchAndFamily = lf.lfPitchAndFamily; cf.bCharSet = lf.lfCharSet; + cf.lcid = GetSystemDefaultLCID(); style = ME_MakeStyle(&cf); text->pDefaultStyle = style; diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 36e082e..8d7d209 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -764,11 +764,28 @@ static void test_EM_SETCHARFORMAT(void) CHARRANGE cr; LOCALESIGNATURE sig; BOOL rtl; + DWORD expect_effects; rtl = (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_FONTSIGNATURE, (LPSTR) &sig, sizeof(LOCALESIGNATURE)) && (sig.lsUsb[3] & 0x08000000) != 0); + /* check charformat defaults */ + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + ok(cf2.dwMask == CFM_ALL2, "got %08x\n", cf2.dwMask); + expect_effects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR; + if (cf2.wWeight > 550) expect_effects |= CFE_BOLD; + ok(cf2.dwEffects == expect_effects, "got %08x\n", cf2.dwEffects); + ok(cf2.yOffset == 0, "got %d\n", cf2.yOffset); + ok(cf2.sSpacing == 0, "got %d\n", cf2.sSpacing); + ok(cf2.lcid == GetSystemDefaultLCID(), "got %x\n", cf2.lcid); + ok(cf2.sStyle == 0, "got %d\n", cf2.sStyle); + ok(cf2.wKerning == 0, "got %d\n", cf2.wKerning); + ok(cf2.bAnimation == 0, "got %d\n", cf2.bAnimation); + ok(cf2.bRevAuthor == 0, "got %d\n", cf2.bRevAuthor); + /* Invalid flags, CHARFORMAT2 structure blanked out */ memset(&cf2, 0, sizeof(cf2)); rc = SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, (WPARAM)0xfffffff0, (LPARAM)&cf2); diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c index 6da3ce3..656eee1 100644 --- a/dlls/riched20/tests/richole.c +++ b/dlls/riched20/tests/richole.c @@ -1741,7 +1741,6 @@ static void test_GetFont(void) value = 0; hr = ITextFont_GetLanguageID(font, &value); ok(hr == S_OK, "got 0x%08x\n", hr); -todo_wine ok(value == GetSystemDefaultLCID(), "got lcid %x, user lcid %x\n", value, GetSystemDefaultLCID()); -- 2.8.2 From huw at codeweavers.com Fri Oct 14 04:05:03 2016 From: huw at codeweavers.com (Huw Davies) Date: Fri, 14 Oct 2016 10:05:03 +0100 Subject: [PATCH 2/6] riched20: Fix the interaction between CFE_UNDERLINE and bUnderlineType. Message-ID: <1476435907-28859-2-git-send-email-huw@codeweavers.com> The effect specifies whether underlining is turned on, while bUnderlineType indicates the type of underlining. Signed-off-by: Huw Davies --- dlls/riched20/editor.c | 29 +++++++++------- dlls/riched20/paint.c | 2 +- dlls/riched20/para.c | 3 +- dlls/riched20/run.c | 10 ------ dlls/riched20/style.c | 53 ++++++++--------------------- dlls/riched20/tests/editor.c | 79 ++++++++++++++++++++++++++++++++++++++++++++ dlls/riched20/writer.c | 23 ++++++------- 7 files changed, 124 insertions(+), 75 deletions(-) diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 8b94ccf..1ce444e 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -427,11 +427,12 @@ void ME_RTFCharAttrHook(RTF_Info *info) { case rtfPlain: /* FIXME add more flags once they're implemented */ - fmt.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINETYPE | CFM_STRIKEOUT | CFM_COLOR | CFM_BACKCOLOR | CFM_SIZE | CFM_WEIGHT; + fmt.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_UNDERLINETYPE | CFM_STRIKEOUT | + CFM_COLOR | CFM_BACKCOLOR | CFM_SIZE | CFM_WEIGHT; fmt.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR; fmt.yHeight = 12*20; /* 12pt */ fmt.wWeight = FW_NORMAL; - fmt.bUnderlineType = CFU_UNDERLINENONE; + fmt.bUnderlineType = CFU_UNDERLINE; break; case rtfBold: fmt.dwMask = CFM_BOLD | CFM_WEIGHT; @@ -443,24 +444,28 @@ void ME_RTFCharAttrHook(RTF_Info *info) fmt.dwEffects = info->rtfParam ? fmt.dwMask : 0; break; case rtfUnderline: - fmt.dwMask = CFM_UNDERLINETYPE; - fmt.bUnderlineType = info->rtfParam ? CFU_CF1UNDERLINE : CFU_UNDERLINENONE; + fmt.dwMask = CFM_UNDERLINETYPE | CFM_UNDERLINE; + fmt.bUnderlineType = CFU_UNDERLINE; + fmt.dwEffects = info->rtfParam ? CFE_UNDERLINE : 0; break; case rtfDotUnderline: - fmt.dwMask = CFM_UNDERLINETYPE; - fmt.bUnderlineType = info->rtfParam ? CFU_UNDERLINEDOTTED : CFU_UNDERLINENONE; + fmt.dwMask = CFM_UNDERLINETYPE | CFM_UNDERLINE; + fmt.bUnderlineType = CFU_UNDERLINEDOTTED; + fmt.dwEffects = info->rtfParam ? CFE_UNDERLINE : 0; break; case rtfDbUnderline: - fmt.dwMask = CFM_UNDERLINETYPE; - fmt.bUnderlineType = info->rtfParam ? CFU_UNDERLINEDOUBLE : CFU_UNDERLINENONE; + fmt.dwMask = CFM_UNDERLINETYPE | CFM_UNDERLINE; + fmt.bUnderlineType = CFU_UNDERLINEDOUBLE; + fmt.dwEffects = info->rtfParam ? CFE_UNDERLINE : 0; break; case rtfWordUnderline: - fmt.dwMask = CFM_UNDERLINETYPE; - fmt.bUnderlineType = info->rtfParam ? CFU_UNDERLINEWORD : CFU_UNDERLINENONE; + fmt.dwMask = CFM_UNDERLINETYPE | CFM_UNDERLINE; + fmt.bUnderlineType = CFU_UNDERLINEWORD; + fmt.dwEffects = info->rtfParam ? CFE_UNDERLINE : 0; break; case rtfNoUnderline: - fmt.dwMask = CFM_UNDERLINETYPE; - fmt.bUnderlineType = CFU_UNDERLINENONE; + fmt.dwMask = CFM_UNDERLINE; + fmt.dwEffects = 0; break; case rtfStrikeThru: fmt.dwMask = CFM_STRIKEOUT; diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c index b76f533..41b3896 100644 --- a/dlls/riched20/paint.c +++ b/dlls/riched20/paint.c @@ -220,7 +220,7 @@ static void get_underline_pen( ME_Style *style, COLORREF color, HPEN *pen ) { *pen = NULL; /* Choose the pen type for underlining the text. */ - if (style->fmt.dwMask & CFM_UNDERLINETYPE) + if (style->fmt.dwEffects & CFE_UNDERLINE) { switch (style->fmt.bUnderlineType) { diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index f050b2e..3f54fea 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -66,7 +66,8 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor) if (lf.lfWeight > FW_NORMAL) cf.dwEffects |= CFE_BOLD; cf.wWeight = lf.lfWeight; if (lf.lfItalic) cf.dwEffects |= CFE_ITALIC; - cf.bUnderlineType = (lf.lfUnderline) ? CFU_CF1UNDERLINE : CFU_UNDERLINENONE; + if (lf.lfUnderline) cf.dwEffects |= CFE_UNDERLINE; + cf.bUnderlineType = CFU_UNDERLINE; if (lf.lfStrikeOut) cf.dwEffects |= CFE_STRIKEOUT; cf.bPitchAndFamily = lf.lfPitchAndFamily; cf.bCharSet = lf.lfCharSet; diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index 496f0f9..098c4f8 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -773,16 +773,6 @@ void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, C static void ME_GetRunCharFormat(ME_TextEditor *editor, ME_DisplayItem *run, CHARFORMAT2W *pFmt) { ME_CopyCharFormat(pFmt, &run->member.run.style->fmt); - if ((pFmt->dwMask & CFM_UNDERLINETYPE) && (pFmt->bUnderlineType == CFU_CF1UNDERLINE)) - { - pFmt->dwMask |= CFM_UNDERLINE; - pFmt->dwEffects |= CFE_UNDERLINE; - } - if ((pFmt->dwMask & CFM_UNDERLINETYPE) && (pFmt->bUnderlineType == CFU_UNDERLINENONE)) - { - pFmt->dwMask |= CFM_UNDERLINE; - pFmt->dwEffects &= ~CFE_UNDERLINE; - } } /****************************************************************************** diff --git a/dlls/riched20/style.c b/dlls/riched20/style.c index 0d2c16a..1a944cbb 100644 --- a/dlls/riched20/style.c +++ b/dlls/riched20/style.c @@ -79,20 +79,6 @@ static CHARFORMAT2W *ME_ToCFAny(CHARFORMAT2W *to, CHARFORMAT2W *from) CHARFORMATA *t = (CHARFORMATA *)to; CopyMemory(t, from, FIELD_OFFSET(CHARFORMATA, szFaceName)); WideCharToMultiByte(CP_ACP, 0, from->szFaceName, -1, t->szFaceName, sizeof(t->szFaceName), NULL, NULL); - if (from->dwMask & CFM_UNDERLINETYPE) - { - switch (from->bUnderlineType) - { - case CFU_CF1UNDERLINE: - to->dwMask |= CFM_UNDERLINE; - to->dwEffects |= CFE_UNDERLINE; - break; - case CFU_UNDERLINENONE: - to->dwMask |= CFM_UNDERLINE; - to->dwEffects &= ~CFE_UNDERLINE; - break; - } - } t->cbSize = sizeof(*t); /* it was overwritten by CopyMemory */ return to; } @@ -100,20 +86,6 @@ static CHARFORMAT2W *ME_ToCFAny(CHARFORMAT2W *to, CHARFORMAT2W *from) { CHARFORMATW *t = (CHARFORMATW *)to; CopyMemory(t, from, sizeof(*t)); - if (from->dwMask & CFM_UNDERLINETYPE) - { - switch (from->bUnderlineType) - { - case CFU_CF1UNDERLINE: - to->dwMask |= CFM_UNDERLINE; - to->dwEffects |= CFE_UNDERLINE; - break; - case CFU_UNDERLINENONE: - to->dwMask |= CFM_UNDERLINE; - to->dwEffects &= ~CFE_UNDERLINE; - break; - } - } t->cbSize = sizeof(*t); /* it was overwritten by CopyMemory */ return to; } @@ -195,7 +167,6 @@ ME_Style *ME_ApplyStyle(ME_TextEditor *editor, ME_Style *sSrc, CHARFORMAT2W *mod } COPY_STYLE_ITEM(CFM_SPACING, sSpacing); COPY_STYLE_ITEM(CFM_STYLE, sStyle); - COPY_STYLE_ITEM(CFM_UNDERLINETYPE, bUnderlineType); COPY_STYLE_ITEM(CFM_WEIGHT, wWeight); /* FIXME: this is not documented this way, but that's the more logical */ COPY_STYLE_ITEM(CFM_FACE, bPitchAndFamily); @@ -210,12 +181,18 @@ ME_Style *ME_ApplyStyle(ME_TextEditor *editor, ME_Style *sSrc, CHARFORMAT2W *mod else fmt.dwEffects &= ~CFE_AUTOCOLOR; } - if (mod->dwMask & CFM_UNDERLINE) + + COPY_STYLE_ITEM(CFM_UNDERLINETYPE, bUnderlineType); + /* If the CFM_UNDERLINE effect is not specified set it appropiately */ + if ((mod->dwMask & CFM_UNDERLINETYPE) && !(mod->dwMask & CFM_UNDERLINE)) { - fmt.dwMask |= CFM_UNDERLINETYPE; - fmt.bUnderlineType = (mod->dwEffects & CFM_UNDERLINE) ? - CFU_CF1UNDERLINE : CFU_UNDERLINENONE; + fmt.dwMask |= CFM_UNDERLINE; + if (mod->bUnderlineType == CFU_UNDERLINENONE) + fmt.dwEffects &= ~CFE_UNDERLINE; + else + fmt.dwEffects |= CFE_UNDERLINE; } + if (mod->dwMask & CFM_BOLD && !(mod->dwMask & CFM_WEIGHT)) { fmt.wWeight = (mod->dwEffects & CFE_BOLD) ? FW_BOLD : FW_NORMAL; @@ -329,9 +306,8 @@ ME_LogFontFromStyle(ME_Context* c, LOGFONTW *lf, const ME_Style *s) lf->lfWeight = s->fmt.wWeight; if (s->fmt.dwEffects & s->fmt.dwMask & CFM_ITALIC) lf->lfItalic = 1; - if (s->fmt.dwEffects & s->fmt.dwMask & (CFM_UNDERLINE | CFE_LINK)) - lf->lfUnderline = 1; - if (s->fmt.dwMask & CFM_UNDERLINETYPE && s->fmt.bUnderlineType == CFU_CF1UNDERLINE) + if ((s->fmt.dwEffects & s->fmt.dwMask & (CFM_UNDERLINE | CFE_LINK)) && + s->fmt.bUnderlineType == CFU_CF1UNDERLINE) lf->lfUnderline = 1; if (s->fmt.dwEffects & s->fmt.dwMask & CFM_STRIKEOUT) lf->lfStrikeOut = 1; @@ -352,14 +328,13 @@ void ME_CharFormatFromLogFont(HDC hDC, const LOGFONTW *lf, CHARFORMAT2W *fmt) ry = GetDeviceCaps(hDC, LOGPIXELSY); lstrcpyW(fmt->szFaceName, lf->lfFaceName); fmt->dwEffects = 0; - fmt->dwMask = CFM_WEIGHT|CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_STRIKEOUT|CFM_SIZE|CFM_FACE|CFM_CHARSET; + fmt->dwMask = CFM_WEIGHT|CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_UNDERLINETYPE|CFM_STRIKEOUT|CFM_SIZE|CFM_FACE|CFM_CHARSET; fmt->wWeight = lf->lfWeight; fmt->yHeight = -lf->lfHeight*1440/ry; if (lf->lfWeight > FW_NORMAL) fmt->dwEffects |= CFM_BOLD; if (lf->lfItalic) fmt->dwEffects |= CFM_ITALIC; if (lf->lfUnderline) fmt->dwEffects |= CFM_UNDERLINE; - /* notice that if a logfont was created with underline due to CFM_LINK, this - would add an erroneous CFM_UNDERLINE. This isn't currently ever a problem. */ + fmt->bUnderlineType = CFU_UNDERLINE; if (lf->lfStrikeOut) fmt->dwEffects |= CFM_STRIKEOUT; fmt->bPitchAndFamily = lf->lfPitchAndFamily; fmt->bCharSet = lf->lfCharSet; diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 8d7d209..bfc61ea 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -1256,6 +1256,85 @@ static void test_EM_SETCHARFORMAT(void) SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cfW); ok(cfW.sSpacing == 10, "got %d\n", cfW.sSpacing); + /* test CFE_UNDERLINE and bUnderlineType interaction */ + /* clear bold, italic */ + SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + cf2.dwMask = CFM_BOLD | CFM_ITALIC; + cf2.dwEffects = 0; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + + /* check CFE_UNDERLINE is clear and bUnderlineType is CFU_UNDERLINE */ + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + ok((cf2.dwMask & (CFM_UNDERLINE | CFM_UNDERLINETYPE)) == (CFM_UNDERLINE | CFM_UNDERLINETYPE), + "got %08x\n", cf2.dwMask); + ok(!(cf2.dwEffects & CFE_UNDERLINE), "got %08x\n", cf2.dwEffects); + ok(cf2.bUnderlineType == CFU_UNDERLINE, "got %x\n", cf2.bUnderlineType); + + /* simply touching bUnderlineType will toggle CFE_UNDERLINE */ + cf2.dwMask = CFM_UNDERLINETYPE; + cf2.bUnderlineType = CFU_UNDERLINE; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + ok((cf2.dwMask & (CFM_UNDERLINE | CFM_UNDERLINETYPE)) == (CFM_UNDERLINE | CFM_UNDERLINETYPE), + "got %08x\n", cf2.dwMask); + ok(cf2.dwEffects & CFE_UNDERLINE, "got %08x\n", cf2.dwEffects); + ok(cf2.bUnderlineType == CFU_UNDERLINE, "got %x\n", cf2.bUnderlineType); + + /* setting bUnderline to CFU_UNDERLINENONE clears CFE_UNDERLINE */ + cf2.dwMask = CFM_UNDERLINETYPE; + cf2.bUnderlineType = CFU_UNDERLINENONE; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + ok((cf2.dwMask & (CFM_UNDERLINE | CFM_UNDERLINETYPE)) == (CFM_UNDERLINE | CFM_UNDERLINETYPE), + "got %08x\n", cf2.dwMask); + ok(!(cf2.dwEffects & CFE_UNDERLINE), "got %08x\n", cf2.dwEffects); + ok(cf2.bUnderlineType == CFU_UNDERLINENONE, "got %x\n", cf2.bUnderlineType); + + /* another underline type also sets CFE_UNDERLINE */ + cf2.dwMask = CFM_UNDERLINETYPE; + cf2.bUnderlineType = CFU_UNDERLINEDOUBLE; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + ok((cf2.dwMask & (CFM_UNDERLINE | CFM_UNDERLINETYPE)) == (CFM_UNDERLINE | CFM_UNDERLINETYPE), + "got %08x\n", cf2.dwMask); + ok(cf2.dwEffects & CFE_UNDERLINE, "got %08x\n", cf2.dwEffects); + ok(cf2.bUnderlineType == CFU_UNDERLINEDOUBLE, "got %x\n", cf2.bUnderlineType); + + /* However explicitly clearing CFE_UNDERLINE results in it remaining cleared */ + cf2.dwMask = CFM_UNDERLINETYPE | CFM_UNDERLINE; + cf2.bUnderlineType = CFU_UNDERLINEDOUBLE; + cf2.dwEffects = 0; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + ok((cf2.dwMask & (CFM_UNDERLINE | CFM_UNDERLINETYPE)) == (CFM_UNDERLINE | CFM_UNDERLINETYPE), + "got %08x\n", cf2.dwMask); + ok(!(cf2.dwEffects & CFE_UNDERLINE), "got %08x\n", cf2.dwEffects); + ok(cf2.bUnderlineType == CFU_UNDERLINEDOUBLE, "got %x\n", cf2.bUnderlineType); + + /* And turing it back on again by just setting CFE_UNDERLINE */ + cf2.dwMask = CFM_UNDERLINE; + cf2.dwEffects = CFE_UNDERLINE; + SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + memset(&cf2, 0, sizeof(CHARFORMAT2A)); + cf2.cbSize = sizeof(CHARFORMAT2A); + SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + ok((cf2.dwMask & (CFM_UNDERLINE | CFM_UNDERLINETYPE)) == (CFM_UNDERLINE | CFM_UNDERLINETYPE), + "got %08x\n", cf2.dwMask); + ok(cf2.dwEffects & CFE_UNDERLINE, "got %08x\n", cf2.dwEffects); + ok(cf2.bUnderlineType == CFU_UNDERLINEDOUBLE, "got %x\n", cf2.bUnderlineType); + DestroyWindow(hwndRichEdit); } diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index 77f50e3..8ecc1601 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -787,29 +787,28 @@ ME_StreamOutRTFCharProps(ME_OutStream *pStream, CHARFORMAT2W *fmt) else if (fmt->dwEffects & CFE_SUPERSCRIPT) strcat(props, "\\super"); } - if (fmt->dwMask & CFM_UNDERLINE || fmt->dwMask & CFM_UNDERLINETYPE) { - if (fmt->dwMask & CFM_UNDERLINETYPE) - switch (fmt->bUnderlineType) { - case CFU_CF1UNDERLINE: - case CFU_UNDERLINE: + if (fmt->dwEffects & CFE_UNDERLINE) + { + switch (fmt->bUnderlineType) + { + case CFU_UNDERLINE: strcat(props, "\\ul"); break; - case CFU_UNDERLINEDOTTED: + case CFU_UNDERLINEDOTTED: strcat(props, "\\uld"); break; - case CFU_UNDERLINEDOUBLE: + case CFU_UNDERLINEDOUBLE: strcat(props, "\\uldb"); break; - case CFU_UNDERLINEWORD: + case CFU_UNDERLINEWORD: strcat(props, "\\ulw"); break; - case CFU_UNDERLINENONE: - default: + case CFU_CF1UNDERLINE: + case CFU_UNDERLINENONE: + default: strcat(props, "\\ulnone"); break; } - else if (fmt->dwEffects & CFE_UNDERLINE) - strcat(props, "\\ul"); } /* FIXME: How to emit CFM_WEIGHT? */ -- 2.8.2 From huw at codeweavers.com Fri Oct 14 04:05:05 2016 From: huw at codeweavers.com (Huw Davies) Date: Fri, 14 Oct 2016 10:05:05 +0100 Subject: [PATCH 4/6] riched20: Simplify call to ME_StreamOutRTFParaProps(). Message-ID: <1476435907-28859-4-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/writer.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index fa20215..d5563a1 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -1012,7 +1012,7 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, const ME_Cursor *start, int nChars, int dwFormat) { ME_Cursor cursor = *start; - ME_DisplayItem *prev_para = cursor.pPara; + ME_DisplayItem *prev_para = NULL; ME_Cursor endCur = cursor; ME_MoveCursorChars(editor, &endCur, nChars, TRUE); @@ -1037,9 +1037,6 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, /* TODO: section formatting properties */ - if (!ME_StreamOutRTFParaProps(editor, pStream, cursor.pPara)) - return FALSE; - do { if (cursor.pPara != prev_para) { -- 2.8.2 From huw at codeweavers.com Fri Oct 14 04:05:04 2016 From: huw at codeweavers.com (Huw Davies) Date: Fri, 14 Oct 2016 10:05:04 +0100 Subject: [PATCH 3/6] riched20: Incrementally update the character format. Message-ID: <1476435907-28859-3-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/editstr.h | 21 -------- dlls/riched20/writer.c | 140 ++++++++++++++++++++++++++++++------------------ 2 files changed, 88 insertions(+), 73 deletions(-) diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index eb4d9f5..eafe2b7 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -373,27 +373,6 @@ struct tagME_InStream { }; typedef struct tagME_InStream ME_InStream; - -#define STREAMOUT_BUFFER_SIZE 4096 -#define STREAMOUT_FONTTBL_SIZE 8192 -#define STREAMOUT_COLORTBL_SIZE 1024 - -typedef struct tagME_OutStream { - EDITSTREAM *stream; - char buffer[STREAMOUT_BUFFER_SIZE]; - UINT pos, written; - UINT nCodePage; - UINT nFontTblLen; - ME_FontTableItem fonttbl[STREAMOUT_FONTTBL_SIZE]; - UINT nColorTblLen; - COLORREF colortbl[STREAMOUT_COLORTBL_SIZE]; - UINT nDefaultFont; - UINT nDefaultCodePage; - /* nNestingLevel = 0 means we aren't in a cell, 1 means we are in a cell, - * an greater numbers mean we are in a cell nested within a cell. */ - UINT nNestingLevel; -} ME_OutStream; - typedef struct tagME_TextEditor { HWND hWnd, hwndParent; diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index 8ecc1601..fa20215 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -28,6 +28,27 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); +#define STREAMOUT_BUFFER_SIZE 4096 +#define STREAMOUT_FONTTBL_SIZE 8192 +#define STREAMOUT_COLORTBL_SIZE 1024 + +typedef struct tagME_OutStream +{ + EDITSTREAM *stream; + char buffer[STREAMOUT_BUFFER_SIZE]; + UINT pos, written; + UINT nCodePage; + UINT nFontTblLen; + ME_FontTableItem fonttbl[STREAMOUT_FONTTBL_SIZE]; + UINT nColorTblLen; + COLORREF colortbl[STREAMOUT_COLORTBL_SIZE]; + UINT nDefaultFont; + UINT nDefaultCodePage; + /* nNestingLevel = 0 means we aren't in a cell, 1 means we are in a cell, + * an greater numbers mean we are in a cell nested within a cell. */ + UINT nNestingLevel; + CHARFORMAT2W cur_fmt; /* current character format */ +} ME_OutStream; static BOOL ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars); @@ -44,6 +65,9 @@ ME_StreamOutInit(ME_TextEditor *editor, EDITSTREAM *stream) pStream->nFontTblLen = 0; pStream->nColorTblLen = 1; pStream->nNestingLevel = 0; + memset(&pStream->cur_fmt, 0, sizeof(pStream->cur_fmt)); + pStream->cur_fmt.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR; + pStream->cur_fmt.bUnderlineType = CFU_UNDERLINE; return pStream; } @@ -710,6 +734,8 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, sprintf(props + strlen(props), "\\cfpat%d\\cbpat%d", (fmt->wShadingStyle >> 4) & 0xF, (fmt->wShadingStyle >> 8) & 0xF); } + if (*props) + strcat(props, " "); if (*props && !ME_StreamOutPrint(pStream, props)) return FALSE; @@ -723,73 +749,87 @@ ME_StreamOutRTFCharProps(ME_OutStream *pStream, CHARFORMAT2W *fmt) { char props[STREAMOUT_BUFFER_SIZE] = ""; unsigned int i; + CHARFORMAT2W *old_fmt = &pStream->cur_fmt; + static const struct + { + DWORD effect; + const char *on, *off; + } effects[] = + { + { CFE_ALLCAPS, "\\caps", "\\caps0" }, + { CFE_BOLD, "\\b", "\\b0" }, + { CFE_DISABLED, "\\disabled", "\\disabled0" }, + { CFE_EMBOSS, "\\embo", "\\embo0" }, + { CFE_HIDDEN, "\\v", "\\v0" }, + { CFE_IMPRINT, "\\impr", "\\impr0" }, + { CFE_ITALIC, "\\i", "\\i0" }, + { CFE_OUTLINE, "\\outl", "\\outl0" }, + { CFE_PROTECTED, "\\protect", "\\protect0" }, + { CFE_SHADOW, "\\shad", "\\shad0" }, + { CFE_SMALLCAPS, "\\scaps", "\\scaps0" }, + { CFE_STRIKEOUT, "\\strike", "\\strike0" }, + }; + + for (i = 0; i < sizeof(effects) / sizeof(effects[0]); i++) + { + if ((old_fmt->dwEffects ^ fmt->dwEffects) & effects[i].effect) + strcat( props, fmt->dwEffects & effects[i].effect ? effects[i].on : effects[i].off ); + } - if (fmt->dwMask & CFM_ALLCAPS && fmt->dwEffects & CFE_ALLCAPS) - strcat(props, "\\caps"); - if (fmt->dwMask & CFM_ANIMATION) - sprintf(props + strlen(props), "\\animtext%u", fmt->bAnimation); - if ((fmt->dwMask & CFM_BACKCOLOR) && !(fmt->dwEffects & CFE_AUTOBACKCOLOR)) - if (find_color_in_colortbl( pStream, fmt->crBackColor, &i )) + if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_AUTOBACKCOLOR || + old_fmt->crBackColor != fmt->crBackColor) + { + if (fmt->dwEffects & CFE_AUTOBACKCOLOR) i = 0; + else find_color_in_colortbl( pStream, fmt->crBackColor, &i ); sprintf(props + strlen(props), "\\cb%u", i); - if (fmt->dwMask & CFM_BOLD && fmt->dwEffects & CFE_BOLD) - strcat(props, "\\b"); - if ((fmt->dwMask & CFM_COLOR) && !(fmt->dwEffects & CFE_AUTOCOLOR)) - if (find_color_in_colortbl( pStream, fmt->crTextColor, &i )) + } + if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_AUTOCOLOR || + old_fmt->crTextColor != fmt->crTextColor) + { + if (fmt->dwEffects & CFE_AUTOCOLOR) i = 0; + else find_color_in_colortbl( pStream, fmt->crTextColor, &i ); sprintf(props + strlen(props), "\\cf%u", i); + } - /* TODO: CFM_DISABLED */ - if (fmt->dwMask & CFM_EMBOSS && fmt->dwEffects & CFE_EMBOSS) - strcat(props, "\\embo"); - if (fmt->dwMask & CFM_HIDDEN && fmt->dwEffects & CFE_HIDDEN) - strcat(props, "\\v"); - if (fmt->dwMask & CFM_IMPRINT && fmt->dwEffects & CFE_IMPRINT) - strcat(props, "\\impr"); - if (fmt->dwMask & CFM_ITALIC && fmt->dwEffects & CFE_ITALIC) - strcat(props, "\\i"); - if (fmt->dwMask & CFM_KERNING) + if (old_fmt->bAnimation != fmt->bAnimation) + sprintf(props + strlen(props), "\\animtext%u", fmt->bAnimation); + if (old_fmt->wKerning != fmt->wKerning) sprintf(props + strlen(props), "\\kerning%u", fmt->wKerning); - if (fmt->dwMask & CFM_LCID) { + + if (old_fmt->lcid != fmt->lcid) + { /* TODO: handle SFF_PLAINRTF */ if (LOWORD(fmt->lcid) == 1024) strcat(props, "\\noproof\\lang1024\\langnp1024\\langfe1024\\langfenp1024"); else sprintf(props + strlen(props), "\\lang%u", LOWORD(fmt->lcid)); } - /* CFM_LINK is not streamed out by M$ */ - if (fmt->dwMask & CFM_OFFSET) { + + if (old_fmt->yOffset != fmt->yOffset) + { if (fmt->yOffset >= 0) sprintf(props + strlen(props), "\\up%d", fmt->yOffset); else sprintf(props + strlen(props), "\\dn%d", -fmt->yOffset); } - if (fmt->dwMask & CFM_OUTLINE && fmt->dwEffects & CFE_OUTLINE) - strcat(props, "\\outl"); - if (fmt->dwMask & CFM_PROTECTED && fmt->dwEffects & CFE_PROTECTED) - strcat(props, "\\protect"); - /* TODO: CFM_REVISED CFM_REVAUTHOR - probably using rsidtbl? */ - if (fmt->dwMask & CFM_SHADOW && fmt->dwEffects & CFE_SHADOW) - strcat(props, "\\shad"); - if (fmt->dwMask & CFM_SIZE) + if (old_fmt->yHeight != fmt->yHeight) sprintf(props + strlen(props), "\\fs%d", fmt->yHeight / 10); - if (fmt->dwMask & CFM_SMALLCAPS && fmt->dwEffects & CFE_SMALLCAPS) - strcat(props, "\\scaps"); - if (fmt->dwMask & CFM_SPACING) + if (old_fmt->sSpacing != fmt->sSpacing) sprintf(props + strlen(props), "\\expnd%u\\expndtw%u", fmt->sSpacing / 5, fmt->sSpacing); - if (fmt->dwMask & CFM_STRIKEOUT && fmt->dwEffects & CFE_STRIKEOUT) - strcat(props, "\\strike"); - if (fmt->dwMask & CFM_STYLE) { - sprintf(props + strlen(props), "\\cs%u", fmt->sStyle); - /* TODO: emit style contents here */ - } - if (fmt->dwMask & (CFM_SUBSCRIPT | CFM_SUPERSCRIPT)) { + if ((old_fmt->dwEffects ^ fmt->dwEffects) & (CFM_SUBSCRIPT | CFM_SUPERSCRIPT)) + { if (fmt->dwEffects & CFE_SUBSCRIPT) strcat(props, "\\sub"); else if (fmt->dwEffects & CFE_SUPERSCRIPT) strcat(props, "\\super"); + else + strcat(props, "\\nosupersub"); } - if (fmt->dwEffects & CFE_UNDERLINE) + if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_UNDERLINE || + old_fmt->bUnderlineType != fmt->bUnderlineType) { - switch (fmt->bUnderlineType) + BYTE type = (fmt->dwEffects & CFE_UNDERLINE) ? fmt->bUnderlineType : CFU_UNDERLINENONE; + switch (type) { case CFU_UNDERLINE: strcat(props, "\\ul"); @@ -810,14 +850,13 @@ ME_StreamOutRTFCharProps(ME_OutStream *pStream, CHARFORMAT2W *fmt) break; } } - /* FIXME: How to emit CFM_WEIGHT? */ - if (fmt->dwMask & CFM_FACE || fmt->dwMask & CFM_CHARSET) + if (strcmpW(old_fmt->szFaceName, fmt->szFaceName) || + old_fmt->bCharSet != fmt->bCharSet) { if (find_font_in_fonttbl( pStream, fmt, &i )) { - if (i != pStream->nDefaultFont) - sprintf(props + strlen(props), "\\f%u", i); + sprintf(props + strlen(props), "\\f%u", i); /* In UTF-8 mode, charsets/codepages are not used */ if (pStream->nDefaultCodePage != CP_UTF8) @@ -833,6 +872,7 @@ ME_StreamOutRTFCharProps(ME_OutStream *pStream, CHARFORMAT2W *fmt) strcat(props, " "); if (!ME_StreamOutPrint(pStream, props)) return FALSE; + *old_fmt = *fmt; return TRUE; } @@ -1045,7 +1085,7 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, if (!ME_StreamOutPrint(pStream, "\\row \r\n")) return FALSE; } else { - if (!ME_StreamOutPrint(pStream, "\r\n\\par")) + if (!ME_StreamOutPrint(pStream, "\\par\r\n")) return FALSE; } /* Skip as many characters as required by current line break */ @@ -1057,8 +1097,6 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, } else { int nEnd; - if (!ME_StreamOutPrint(pStream, "{")) - return FALSE; TRACE("style %p\n", cursor.pRun->member.run.style); if (!ME_StreamOutRTFCharProps(pStream, &cursor.pRun->member.run.style->fmt)) return FALSE; @@ -1068,8 +1106,6 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, nEnd - cursor.nOffset)) return FALSE; cursor.nOffset = 0; - if (!ME_StreamOutPrint(pStream, "}")) - return FALSE; } } while (cursor.pRun != endCur.pRun && ME_NextRun(&cursor.pPara, &cursor.pRun, TRUE)); -- 2.8.2 From huw at codeweavers.com Fri Oct 14 04:05:06 2016 From: huw at codeweavers.com (Huw Davies) Date: Fri, 14 Oct 2016 10:05:06 +0100 Subject: [PATCH 5/6] riched20: Remove the question marks from the generator string. Message-ID: <1476435907-28859-5-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/writer.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index d5563a1..44b9246 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -1025,8 +1025,7 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, /* TODO: stylesheet table */ - /* FIXME: maybe emit something smarter for the generator? */ - if (!ME_StreamOutPrint(pStream, "{\\*\\generator Wine Riched20 2.0.????;}")) + if (!ME_StreamOutPrint(pStream, "{\\*\\generator Wine Riched20 2.0;}")) return FALSE; /* TODO: information group */ -- 2.8.2 From huw at codeweavers.com Fri Oct 14 04:05:07 2016 From: huw at codeweavers.com (Huw Davies) Date: Fri, 14 Oct 2016 10:05:07 +0100 Subject: [PATCH 6/6] riched20: Remove unnecessary spaces before carriage returns. Message-ID: <1476435907-28859-6-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/riched20/writer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index 44b9246..baa2886 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -580,7 +580,7 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, if (!ME_StreamOutPrint(pStream, "\\nestrow}{\\nonesttables\\par}\r\n")) return FALSE; } else { - if (!ME_StreamOutPrint(pStream, "\\row \r\n")) + if (!ME_StreamOutPrint(pStream, "\\row\r\n")) return FALSE; } return TRUE; @@ -1078,7 +1078,7 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, cursor.pPara->member.para.fmt.wEffects & PFE_TABLE && !(cursor.pPara->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND|MEPF_CELL))) { - if (!ME_StreamOutPrint(pStream, "\\row \r\n")) + if (!ME_StreamOutPrint(pStream, "\\row\r\n")) return FALSE; } else { if (!ME_StreamOutPrint(pStream, "\\par\r\n")) @@ -1087,7 +1087,7 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, /* Skip as many characters as required by current line break */ nChars = max(0, nChars - cursor.pRun->member.run.len); } else if (cursor.pRun->member.run.nFlags & MERF_ENDROW) { - if (!ME_StreamOutPrint(pStream, "\\line \r\n")) + if (!ME_StreamOutPrint(pStream, "\\line\r\n")) return FALSE; nChars--; } else { -- 2.8.2 From aric at codeweavers.com Fri Oct 14 04:36:16 2016 From: aric at codeweavers.com (Aric Stewart) Date: Fri, 14 Oct 2016 11:36:16 +0200 Subject: [PATCH] hid/tests: Add HID device enumeration test Message-ID: Signed-off-by: Aric Stewart --- configure | 1 + configure.ac | 1 + dlls/hid/tests/Makefile.in | 5 +++ dlls/hid/tests/device.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 dlls/hid/tests/Makefile.in create mode 100644 dlls/hid/tests/device.c -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-hid-tests-Add-HID-device-enumeration-test.txt Type: text/x-patch Size: 4358 bytes Desc: not available URL: From berencamlost at msn.com Fri Oct 14 04:58:02 2016 From: berencamlost at msn.com (Kim Malmo) Date: Fri, 14 Oct 2016 09:58:02 +0000 Subject: [PATCH] po: Some more updates to Norwegian translation Message-ID: Signed-off-by: Kim Malmo --- po/nb_NO.po | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/po/nb_NO.po b/po/nb_NO.po index e90627a..f81286a 100644 --- a/po/nb_NO.po +++ b/po/nb_NO.po @@ -10506,10 +10506,8 @@ msgid "IPv6 address" msgstr "IPv6-adresse" #: msinfo32.rc:28 -#, fuzzy -#| msgid "System Configuration" msgid "System Information" -msgstr "Systemoppsett" +msgstr "Systeminformasjon" #: net.rc:30 msgid "" @@ -14578,36 +14576,32 @@ msgid "F&ormat" msgstr "F&ormat" #: wordpad.rc:85 -#, fuzzy -#| msgid "&List" msgid "&Lists" -msgstr "&Liste" +msgstr "&Lister" #: wordpad.rc:87 wordpad.rc:116 msgid "&Bullet points" msgstr "&Punktmerking" #: wordpad.rc:88 -#, fuzzy -#| msgid "CRL Number" msgid "Numbers" -msgstr "CRL-nummer" +msgstr "Numre" #: wordpad.rc:89 msgid "Letters - lower case" -msgstr "" +msgstr "Små bokstaver" #: wordpad.rc:90 msgid "Letters - upper case" -msgstr "" +msgstr "Store bokstaver" #: wordpad.rc:91 msgid "Roman numerals - lower case" -msgstr "" +msgstr "Små romertall" #: wordpad.rc:92 msgid "Roman numerals - upper case" -msgstr "" +msgstr "Store romertall" #: wordpad.rc:94 wordpad.rc:117 msgid "&Paragraph..." -- 1.9.1 From hverbeet at codeweavers.com Fri Oct 14 05:46:18 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 14 Oct 2016 12:46:18 +0200 Subject: [PATCH 2/5] wined3d: Recognize a couple of Haswell / Broadwell GPUs on macOS. In-Reply-To: <1476396217-26826-2-git-send-email-mbruni@codeweavers.com> References: <1476396217-26826-2-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 14 05:46:19 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 14 Oct 2016 12:46:19 +0200 Subject: [PATCH 3/5] wined3d: Add a bunch of Broadwell and Skylake PCI ids and descriptions. In-Reply-To: <1476396217-26826-3-git-send-email-mbruni@codeweavers.com> References: <1476396217-26826-3-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 14 05:46:21 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 14 Oct 2016 12:46:21 +0200 Subject: [PATCH 5/5] wined3d: Store blit quad texture coordinates in a struct wined3d_vec3 array. In-Reply-To: <1476396217-26826-5-git-send-email-mbruni@codeweavers.com> References: <1476396217-26826-5-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 14 05:46:20 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 14 Oct 2016 12:46:20 +0200 Subject: [PATCH 4/5] wined3d: Ignore driver model if the requested driver model entry is missing. In-Reply-To: <1476396217-26826-4-git-send-email-mbruni@codeweavers.com> References: <1476396217-26826-4-git-send-email-mbruni@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From andrey.goosev at gmail.com Fri Oct 14 06:56:00 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Fri, 14 Oct 2016 14:56:00 +0300 Subject: api-ms-win-appmodel-runtime-l1-1-1: Add dll. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: api-ms-win-appmodel-runtime-l1-1-1-Add-dll.patch Type: text/x-patch Size: 4083 bytes Desc: not available URL: From andrey.goosev at gmail.com Fri Oct 14 06:57:47 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Fri, 14 Oct 2016 14:57:47 +0300 Subject: ext-ms-win-kernel32-package-current-l1-1-0: Add dll. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: ext-ms-win-kernel32-package-current-l1-1-0-Add-dll.patch Type: text/x-patch Size: 3284 bytes Desc: not available URL: From nsivov at codeweavers.com Fri Oct 14 11:12:16 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Fri, 14 Oct 2016 19:12:16 +0300 Subject: [PATCH] d2d1: Initial implementation of bitmap render target Message-ID: <20161014161216.8112-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/d2d1/Makefile.in | 1 + dlls/d2d1/bitmap_render_target.c | 834 +++++++++++++++++++++++++++++++++++++++ dlls/d2d1/brush.c | 4 +- dlls/d2d1/d2d1_private.h | 18 +- dlls/d2d1/render_target.c | 68 ++-- dlls/d2d1/tests/d2d1.c | 13 +- 6 files changed, 897 insertions(+), 41 deletions(-) create mode 100644 dlls/d2d1/bitmap_render_target.c diff --git a/dlls/d2d1/Makefile.in b/dlls/d2d1/Makefile.in index deacd7a..68e9268 100644 --- a/dlls/d2d1/Makefile.in +++ b/dlls/d2d1/Makefile.in @@ -5,6 +5,7 @@ DELAYIMPORTS = dwrite C_SRCS = \ bitmap.c \ + bitmap_render_target.c \ brush.c \ dc_render_target.c \ factory.c \ diff --git a/dlls/d2d1/bitmap_render_target.c b/dlls/d2d1/bitmap_render_target.c new file mode 100644 index 0000000..4fd7e02 --- /dev/null +++ b/dlls/d2d1/bitmap_render_target.c @@ -0,0 +1,834 @@ +/* + * Copyright 2014 Henri Verbeet for CodeWeavers + * Copyright 2016 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include "d2d1_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d2d); + +static inline struct d2d_bitmap_render_target *impl_from_ID2D1BitmapRenderTarget(ID2D1BitmapRenderTarget *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_bitmap_render_target, ID2D1BitmapRenderTarget_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_QueryInterface(ID2D1BitmapRenderTarget *iface, + REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1BitmapRenderTarget) + || IsEqualGUID(iid, &IID_ID2D1RenderTarget) + || IsEqualGUID(iid, &IID_ID2D1Resource) + || IsEqualGUID(iid, &IID_IUnknown)) + { + ID2D1BitmapRenderTarget_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_bitmap_render_target_AddRef(ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + ULONG refcount = InterlockedIncrement(&render_target->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_bitmap_render_target_Release(ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + ULONG refcount = InterlockedDecrement(&render_target->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (!refcount) + { + ID2D1RenderTarget_Release(render_target->dxgi_target); + ID2D1Bitmap_Release(render_target->bitmap); + HeapFree(GetProcessHeap(), 0, render_target); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_GetFactory(ID2D1BitmapRenderTarget *iface, + ID2D1Factory **factory) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, factory %p.\n", iface, factory); + + ID2D1RenderTarget_GetFactory(render_target->dxgi_target, factory); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateBitmap(ID2D1BitmapRenderTarget *iface, + D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, size {%u, %u}, src_data %p, pitch %u, desc %p, bitmap %p.\n", + iface, size.width, size.height, src_data, pitch, desc, bitmap); + + return ID2D1RenderTarget_CreateBitmap(render_target->dxgi_target, size, src_data, pitch, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateBitmapFromWicBitmap(ID2D1BitmapRenderTarget *iface, + IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, bitmap_source %p, desc %p, bitmap %p.\n", + iface, bitmap_source, desc, bitmap); + + return ID2D1RenderTarget_CreateBitmapFromWicBitmap(render_target->dxgi_target, bitmap_source, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateSharedBitmap(ID2D1BitmapRenderTarget *iface, + REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, iid %s, data %p, desc %p, bitmap %p.\n", + iface, debugstr_guid(iid), data, desc, bitmap); + + return ID2D1RenderTarget_CreateSharedBitmap(render_target->dxgi_target, iid, data, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateBitmapBrush(ID2D1BitmapRenderTarget *iface, + ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc, + const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1BitmapBrush **brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p.\n", + iface, bitmap, bitmap_brush_desc, brush_desc, brush); + + return ID2D1RenderTarget_CreateBitmapBrush(render_target->dxgi_target, + bitmap, bitmap_brush_desc, brush_desc, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateSolidColorBrush(ID2D1BitmapRenderTarget *iface, + const D2D1_COLOR_F *color, const D2D1_BRUSH_PROPERTIES *desc, ID2D1SolidColorBrush **brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, color %p, desc %p, brush %p.\n", iface, color, desc, brush); + + return ID2D1RenderTarget_CreateSolidColorBrush(render_target->dxgi_target, color, desc, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateGradientStopCollection(ID2D1BitmapRenderTarget *iface, + const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode, + ID2D1GradientStopCollection **gradient) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n", + iface, stops, stop_count, gamma, extend_mode, gradient); + + return ID2D1RenderTarget_CreateGradientStopCollection(render_target->dxgi_target, + stops, stop_count, gamma, extend_mode, gradient); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateLinearGradientBrush(ID2D1BitmapRenderTarget *iface, + const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1GradientStopCollection *gradient, ID2D1LinearGradientBrush **brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n", + iface, gradient_brush_desc, brush_desc, gradient, brush); + + return ID2D1RenderTarget_CreateLinearGradientBrush(render_target->dxgi_target, + gradient_brush_desc, brush_desc, gradient, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateRadialGradientBrush(ID2D1BitmapRenderTarget *iface, + const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1GradientStopCollection *gradient, ID2D1RadialGradientBrush **brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n", + iface, gradient_brush_desc, brush_desc, gradient, brush); + + return ID2D1RenderTarget_CreateRadialGradientBrush(render_target->dxgi_target, + gradient_brush_desc, brush_desc, gradient, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateCompatibleRenderTarget(ID2D1BitmapRenderTarget *iface, + const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **render_target) +{ + struct d2d_bitmap_render_target *rt = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p,\n", + iface, size, pixel_size, format, options, render_target); + + return ID2D1RenderTarget_CreateCompatibleRenderTarget(rt->dxgi_target, + size, pixel_size, format, options, render_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateLayer(ID2D1BitmapRenderTarget *iface, + const D2D1_SIZE_F *size, ID2D1Layer **layer) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, size %p, layer %p.\n", iface, size, layer); + + return ID2D1RenderTarget_CreateLayer(render_target->dxgi_target, size, layer); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateMesh(ID2D1BitmapRenderTarget *iface, ID2D1Mesh **mesh) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, mesh %p.\n", iface, mesh); + + return ID2D1RenderTarget_CreateMesh(render_target->dxgi_target, mesh); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawLine(ID2D1BitmapRenderTarget *iface, + D2D1_POINT_2F p0, D2D1_POINT_2F p1, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, p0 {%.8e, %.8e}, p1 {%.8e, %.8e}, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, p0.x, p0.y, p1.x, p1.y, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawLine(render_target->dxgi_target, p0, p1, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawRectangle(ID2D1BitmapRenderTarget *iface, + const D2D1_RECT_F *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, rect, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawRectangle(render_target->dxgi_target, rect, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_FillRectangle(ID2D1BitmapRenderTarget *iface, + const D2D1_RECT_F *rect, ID2D1Brush *brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p.\n", iface, rect, brush); + + ID2D1RenderTarget_FillRectangle(render_target->dxgi_target, rect, brush); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawRoundedRectangle(ID2D1BitmapRenderTarget *iface, + const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, rect, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawRoundedRectangle(render_target->dxgi_target, rect, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_FillRoundedRectangle(ID2D1BitmapRenderTarget *iface, + const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p.\n", iface, rect, brush); + + ID2D1RenderTarget_FillRoundedRectangle(render_target->dxgi_target, rect, brush); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawEllipse(ID2D1BitmapRenderTarget *iface, + const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, ellipse %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, ellipse, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawEllipse(render_target->dxgi_target, ellipse, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_FillEllipse(ID2D1BitmapRenderTarget *iface, + const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, ellipse %p, brush %p.\n", iface, ellipse, brush); + + ID2D1RenderTarget_FillEllipse(render_target->dxgi_target, ellipse, brush); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawGeometry(ID2D1BitmapRenderTarget *iface, + ID2D1Geometry *geometry, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, geometry %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, geometry, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawGeometry(render_target->dxgi_target, geometry, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_FillGeometry(ID2D1BitmapRenderTarget *iface, + ID2D1Geometry *geometry, ID2D1Brush *brush, ID2D1Brush *opacity_brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, geometry %p, brush %p, opacity_brush %p.\n", iface, geometry, brush, opacity_brush); + + ID2D1RenderTarget_FillGeometry(render_target->dxgi_target, geometry, brush, opacity_brush); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_FillMesh(ID2D1BitmapRenderTarget *iface, + ID2D1Mesh *mesh, ID2D1Brush *brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, mesh %p, brush %p.\n", iface, mesh, brush); + + ID2D1RenderTarget_FillMesh(render_target->dxgi_target, mesh, brush); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_FillOpacityMask(ID2D1BitmapRenderTarget *iface, + ID2D1Bitmap *mask, ID2D1Brush *brush, D2D1_OPACITY_MASK_CONTENT content, + const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, mask %p, brush %p, content %#x, dst_rect %p, src_rect %p.\n", + iface, mask, brush, content, dst_rect, src_rect); + + ID2D1RenderTarget_FillOpacityMask(render_target->dxgi_target, + mask, brush, content, dst_rect, src_rect); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawBitmap(ID2D1BitmapRenderTarget *iface, + ID2D1Bitmap *bitmap, const D2D1_RECT_F *dst_rect, float opacity, + D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, const D2D1_RECT_F *src_rect) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, bitmap %p, dst_rect %p, opacity %.8e, interpolation_mode %#x, src_rect %p.\n", + iface, bitmap, dst_rect, opacity, interpolation_mode, src_rect); + + ID2D1RenderTarget_DrawBitmap(render_target->dxgi_target, + bitmap, dst_rect, opacity, interpolation_mode, src_rect); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawText(ID2D1BitmapRenderTarget *iface, + const WCHAR *string, UINT32 string_len, IDWriteTextFormat *text_format, const D2D1_RECT_F *layout_rect, + ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuring_mode) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, string %s, string_len %u, text_format %p, layout_rect %p, " + "brush %p, options %#x, measuring_mode %#x.\n", + iface, debugstr_wn(string, string_len), string_len, text_format, layout_rect, + brush, options, measuring_mode); + + ID2D1RenderTarget_DrawText(render_target->dxgi_target, string, string_len, + text_format, layout_rect, brush, options, measuring_mode); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawTextLayout(ID2D1BitmapRenderTarget *iface, + D2D1_POINT_2F origin, IDWriteTextLayout *layout, ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, origin {%.8e, %.8e}, layout %p, brush %p, options %#x.\n", + iface, origin.x, origin.y, layout, brush, options); + + ID2D1RenderTarget_DrawTextLayout(render_target->dxgi_target, origin, layout, brush, options); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawGlyphRun(ID2D1BitmapRenderTarget *iface, + D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush, + DWRITE_MEASURING_MODE measuring_mode) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, baseline_origin {%.8e, %.8e}, glyph_run %p, brush %p, measuring_mode %#x.\n", + iface, baseline_origin.x, baseline_origin.y, glyph_run, brush, measuring_mode); + + ID2D1RenderTarget_DrawGlyphRun(render_target->dxgi_target, + baseline_origin, glyph_run, brush, measuring_mode); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_SetTransform(ID2D1BitmapRenderTarget *iface, + const D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, transform %p.\n", iface, transform); + + ID2D1RenderTarget_SetTransform(render_target->dxgi_target, transform); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_GetTransform(ID2D1BitmapRenderTarget *iface, + D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, transform %p.\n", iface, transform); + + ID2D1RenderTarget_GetTransform(render_target->dxgi_target, transform); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_SetAntialiasMode(ID2D1BitmapRenderTarget *iface, + D2D1_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, antialias_mode %#x.\n", iface, antialias_mode); + + ID2D1RenderTarget_SetAntialiasMode(render_target->dxgi_target, antialias_mode); +} + +static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_bitmap_render_target_GetAntialiasMode(ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetAntialiasMode(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_SetTextAntialiasMode(ID2D1BitmapRenderTarget *iface, + D2D1_TEXT_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, antialias_mode %#x.\n", iface, antialias_mode); + + ID2D1RenderTarget_SetTextAntialiasMode(render_target->dxgi_target, antialias_mode); +} + +static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_bitmap_render_target_GetTextAntialiasMode( + ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetTextAntialiasMode(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_SetTextRenderingParams(ID2D1BitmapRenderTarget *iface, + IDWriteRenderingParams *text_rendering_params) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params); + + ID2D1RenderTarget_SetTextRenderingParams(render_target->dxgi_target, text_rendering_params); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_GetTextRenderingParams(ID2D1BitmapRenderTarget *iface, + IDWriteRenderingParams **text_rendering_params) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params); + + ID2D1RenderTarget_GetTextRenderingParams(render_target->dxgi_target, text_rendering_params); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_SetTags(ID2D1BitmapRenderTarget *iface, D2D1_TAG tag1, + D2D1_TAG tag2) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, tag1 %s, tag2 %s.\n", iface, wine_dbgstr_longlong(tag1), wine_dbgstr_longlong(tag2)); + + ID2D1RenderTarget_SetTags(render_target->dxgi_target, tag1, tag2); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_GetTags(ID2D1BitmapRenderTarget *iface, D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + ID2D1RenderTarget_GetTags(render_target->dxgi_target, tag1, tag2); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_PushLayer(ID2D1BitmapRenderTarget *iface, + const D2D1_LAYER_PARAMETERS *layer_parameters, ID2D1Layer *layer) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, layer_parameters %p, layer %p.\n", iface, layer_parameters, layer); + + ID2D1RenderTarget_PushLayer(render_target->dxgi_target, layer_parameters, layer); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_PopLayer(ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_PopLayer(render_target->dxgi_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_Flush(ID2D1BitmapRenderTarget *iface, D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + return ID2D1RenderTarget_Flush(render_target->dxgi_target, tag1, tag2); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_SaveDrawingState(ID2D1BitmapRenderTarget *iface, + ID2D1DrawingStateBlock *state_block) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, state_block %p.\n", iface, state_block); + + ID2D1RenderTarget_SaveDrawingState(render_target->dxgi_target, state_block); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_RestoreDrawingState(ID2D1BitmapRenderTarget *iface, + ID2D1DrawingStateBlock *state_block) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, state_block %p.\n", iface, state_block); + + ID2D1RenderTarget_RestoreDrawingState(render_target->dxgi_target, state_block); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_PushAxisAlignedClip(ID2D1BitmapRenderTarget *iface, + const D2D1_RECT_F *clip_rect, D2D1_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, clip_rect %p, antialias_mode %#x.\n", iface, clip_rect, antialias_mode); + + ID2D1RenderTarget_PushAxisAlignedClip(render_target->dxgi_target, clip_rect, antialias_mode); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_PopAxisAlignedClip(ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_PopAxisAlignedClip(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_Clear(ID2D1BitmapRenderTarget *iface, const D2D1_COLOR_F *color) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, color %p.\n", iface, color); + + ID2D1RenderTarget_Clear(render_target->dxgi_target, color); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_BeginDraw(ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_BeginDraw(render_target->dxgi_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_EndDraw(ID2D1BitmapRenderTarget *iface, + D2D1_TAG *tag1, D2D1_TAG *tag2) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + return ID2D1RenderTarget_EndDraw(render_target->dxgi_target, tag1, tag2); +} + +static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_bitmap_render_target_GetPixelFormat(ID2D1BitmapRenderTarget *iface, + D2D1_PIXEL_FORMAT *format) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, format %p.\n", iface, format); + + *format = ID2D1RenderTarget_GetPixelFormat(render_target->dxgi_target); + return format; +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_SetDpi(ID2D1BitmapRenderTarget *iface, float dpi_x, float dpi_y) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, dpi_x %.8e, dpi_y %.8e.\n", iface, dpi_x, dpi_y); + + ID2D1RenderTarget_SetDpi(render_target->dxgi_target, dpi_x, dpi_y); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_GetDpi(ID2D1BitmapRenderTarget *iface, + float *dpi_x, float *dpi_y) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y); + + ID2D1RenderTarget_GetDpi(render_target->dxgi_target, dpi_x, dpi_y); +} + +static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_bitmap_render_target_GetSize(ID2D1BitmapRenderTarget *iface, + D2D1_SIZE_F *size) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, size %p.\n", iface, size); + + *size = ID2D1RenderTarget_GetSize(render_target->dxgi_target); + return size; +} + +static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_bitmap_render_target_GetPixelSize(ID2D1BitmapRenderTarget *iface, + D2D1_SIZE_U *pixel_size) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, pixel_size %p.\n", iface, pixel_size); + + *pixel_size = ID2D1RenderTarget_GetPixelSize(render_target->dxgi_target); + return pixel_size; +} + +static UINT32 STDMETHODCALLTYPE d2d_bitmap_render_target_GetMaximumBitmapSize(ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetMaximumBitmapSize(render_target->dxgi_target); +} + +static BOOL STDMETHODCALLTYPE d2d_bitmap_render_target_IsSupported(ID2D1BitmapRenderTarget *iface, + const D2D1_RENDER_TARGET_PROPERTIES *desc) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + return ID2D1RenderTarget_IsSupported(render_target->dxgi_target, desc); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_GetBitmap(ID2D1BitmapRenderTarget *iface, + ID2D1Bitmap **bitmap) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, bitmap %p.\n", iface, bitmap); + + ID2D1Bitmap_AddRef(*bitmap = render_target->bitmap); + return S_OK; +} + +static const struct ID2D1BitmapRenderTargetVtbl d2d_bitmap_render_target_vtbl = +{ + d2d_bitmap_render_target_QueryInterface, + d2d_bitmap_render_target_AddRef, + d2d_bitmap_render_target_Release, + d2d_bitmap_render_target_GetFactory, + d2d_bitmap_render_target_CreateBitmap, + d2d_bitmap_render_target_CreateBitmapFromWicBitmap, + d2d_bitmap_render_target_CreateSharedBitmap, + d2d_bitmap_render_target_CreateBitmapBrush, + d2d_bitmap_render_target_CreateSolidColorBrush, + d2d_bitmap_render_target_CreateGradientStopCollection, + d2d_bitmap_render_target_CreateLinearGradientBrush, + d2d_bitmap_render_target_CreateRadialGradientBrush, + d2d_bitmap_render_target_CreateCompatibleRenderTarget, + d2d_bitmap_render_target_CreateLayer, + d2d_bitmap_render_target_CreateMesh, + d2d_bitmap_render_target_DrawLine, + d2d_bitmap_render_target_DrawRectangle, + d2d_bitmap_render_target_FillRectangle, + d2d_bitmap_render_target_DrawRoundedRectangle, + d2d_bitmap_render_target_FillRoundedRectangle, + d2d_bitmap_render_target_DrawEllipse, + d2d_bitmap_render_target_FillEllipse, + d2d_bitmap_render_target_DrawGeometry, + d2d_bitmap_render_target_FillGeometry, + d2d_bitmap_render_target_FillMesh, + d2d_bitmap_render_target_FillOpacityMask, + d2d_bitmap_render_target_DrawBitmap, + d2d_bitmap_render_target_DrawText, + d2d_bitmap_render_target_DrawTextLayout, + d2d_bitmap_render_target_DrawGlyphRun, + d2d_bitmap_render_target_SetTransform, + d2d_bitmap_render_target_GetTransform, + d2d_bitmap_render_target_SetAntialiasMode, + d2d_bitmap_render_target_GetAntialiasMode, + d2d_bitmap_render_target_SetTextAntialiasMode, + d2d_bitmap_render_target_GetTextAntialiasMode, + d2d_bitmap_render_target_SetTextRenderingParams, + d2d_bitmap_render_target_GetTextRenderingParams, + d2d_bitmap_render_target_SetTags, + d2d_bitmap_render_target_GetTags, + d2d_bitmap_render_target_PushLayer, + d2d_bitmap_render_target_PopLayer, + d2d_bitmap_render_target_Flush, + d2d_bitmap_render_target_SaveDrawingState, + d2d_bitmap_render_target_RestoreDrawingState, + d2d_bitmap_render_target_PushAxisAlignedClip, + d2d_bitmap_render_target_PopAxisAlignedClip, + d2d_bitmap_render_target_Clear, + d2d_bitmap_render_target_BeginDraw, + d2d_bitmap_render_target_EndDraw, + d2d_bitmap_render_target_GetPixelFormat, + d2d_bitmap_render_target_SetDpi, + d2d_bitmap_render_target_GetDpi, + d2d_bitmap_render_target_GetSize, + d2d_bitmap_render_target_GetPixelSize, + d2d_bitmap_render_target_GetMaximumBitmapSize, + d2d_bitmap_render_target_IsSupported, + d2d_bitmap_render_target_GetBitmap +}; + +HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_target, + const struct d2d_d3d_render_target *parent_target, const D2D1_SIZE_F *size, + const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *pixel_format, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options) +{ + D2D1_RENDER_TARGET_PROPERTIES dxgi_rt_desc; + D2D1_BITMAP_PROPERTIES bitmap_desc; + D3D10_TEXTURE2D_DESC texture_desc; + IDXGISurface *dxgi_surface; + ID3D10Texture2D *texture; + HRESULT hr; + + if (options) + FIXME("Compatible target options are ignored, %#x.\n", options); + + render_target->ID2D1BitmapRenderTarget_iface.lpVtbl = &d2d_bitmap_render_target_vtbl; + render_target->refcount = 1; + + dxgi_rt_desc.type = parent_target->desc.type; + dxgi_rt_desc.usage = parent_target->desc.usage; + dxgi_rt_desc.minLevel = parent_target->desc.minLevel; + + if (!pixel_size && size) + { + texture_desc.Width = ceilf((size->width * parent_target->desc.dpiX) / 96.0f); + texture_desc.Height = ceilf((size->height * parent_target->desc.dpiY) / 96.0f); + dxgi_rt_desc.dpiX = (texture_desc.Width * 96.0f) / size->width; + dxgi_rt_desc.dpiY = (texture_desc.Height * 96.0f) / size->height; + } + else if (pixel_size && !size) + { + texture_desc.Width = pixel_size->width; + texture_desc.Height = pixel_size->height; + dxgi_rt_desc.dpiX = parent_target->desc.dpiX; + dxgi_rt_desc.dpiY = parent_target->desc.dpiY; + } + else if (pixel_size && size) + { + texture_desc.Width = pixel_size->width; + texture_desc.Height = pixel_size->height; + dxgi_rt_desc.dpiX = (pixel_size->width * 96.0f) / size->width; + dxgi_rt_desc.dpiY = (pixel_size->height * 96.0f) / size->height; + } + else + { + texture_desc.Width = parent_target->pixel_size.width; + texture_desc.Height = parent_target->pixel_size.height; + dxgi_rt_desc.dpiX = parent_target->desc.dpiX; + dxgi_rt_desc.dpiY = parent_target->desc.dpiY; + } + + if (!pixel_format || pixel_format->format == DXGI_FORMAT_UNKNOWN) + texture_desc.Format = parent_target->desc.pixelFormat.format; + else + texture_desc.Format = pixel_format->format; + dxgi_rt_desc.pixelFormat.format = texture_desc.Format; + + if (!pixel_format || pixel_format->alphaMode == D2D1_ALPHA_MODE_UNKNOWN) + dxgi_rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + else + dxgi_rt_desc.pixelFormat.alphaMode = pixel_format->alphaMode; + + texture_desc.MipLevels = 1; + texture_desc.ArraySize = 1; + texture_desc.SampleDesc.Count = 1; + texture_desc.SampleDesc.Quality = 0; + texture_desc.Usage = D3D10_USAGE_DEFAULT; + texture_desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE; + texture_desc.CPUAccessFlags = 0; + texture_desc.MiscFlags = 0; + + if (FAILED(hr = ID3D10Device_CreateTexture2D(parent_target->device, &texture_desc, NULL, &texture))) + { + WARN("Failed to create texture, hr %#x.\n", hr); + return hr; + } + + hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&dxgi_surface); + ID3D10Texture2D_Release(texture); + if (FAILED(hr)) + { + WARN("Failed to get DXGI surface interface, hr %#x.\n", hr); + return hr; + } + + if (FAILED(hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(parent_target->factory, dxgi_surface, &dxgi_rt_desc, + &render_target->dxgi_target))) + { + WARN("Failed to create DXGI surface render target, hr %#x.\n", hr); + IDXGISurface_Release(dxgi_surface); + return hr; + } + + bitmap_desc.pixelFormat = dxgi_rt_desc.pixelFormat; + bitmap_desc.dpiX = dxgi_rt_desc.dpiX; + bitmap_desc.dpiY = dxgi_rt_desc.dpiY; + + hr = ID2D1RenderTarget_CreateSharedBitmap(render_target->dxgi_target, &IID_IDXGISurface, dxgi_surface, + &bitmap_desc, &render_target->bitmap); + IDXGISurface_Release(dxgi_surface); + if (FAILED(hr)) + { + WARN("Failed to create shared bitmap, hr %#x.\n", hr); + ID2D1RenderTarget_Release(render_target->dxgi_target); + return hr; + } + + return S_OK; +} diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c index 1454faf..38872ea 100644 --- a/dlls/d2d1/brush.c +++ b/dlls/d2d1/brush.c @@ -789,11 +789,11 @@ static BOOL d2d_brush_fill_cb(struct d2d_brush *brush, struct d2d_d3d_render_tar /* Scale for dpi. */ w = render_target->drawing_state.transform; - dpi_scale = render_target->dpi_x / 96.0f; + dpi_scale = render_target->desc.dpiX / 96.0f; w._11 *= dpi_scale; w._21 *= dpi_scale; w._31 *= dpi_scale; - dpi_scale = render_target->dpi_y / 96.0f; + dpi_scale = render_target->desc.dpiY / 96.0f; w._12 *= dpi_scale; w._22 *= dpi_scale; w._32 *= dpi_scale; diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index c5c3a03..b49fce4 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -87,11 +87,9 @@ struct d2d_d3d_render_target IDWriteRenderingParams *text_rendering_params; IDWriteRenderingParams *default_text_rendering_params; - D2D1_PIXEL_FORMAT format; + D2D1_RENDER_TARGET_PROPERTIES desc; D2D1_SIZE_U pixel_size; struct d2d_clip_stack clip_stack; - float dpi_x; - float dpi_y; }; HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory, @@ -146,6 +144,20 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc, const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_desc) DECLSPEC_HIDDEN; +struct d2d_bitmap_render_target +{ + ID2D1BitmapRenderTarget ID2D1BitmapRenderTarget_iface; + LONG refcount; + + ID2D1RenderTarget *dxgi_target; + ID2D1Bitmap *bitmap; +}; + +HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_target, + const struct d2d_d3d_render_target *parent_target, const D2D1_SIZE_F *size, + const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options) DECLSPEC_HIDDEN; + struct d2d_gradient { ID2D1GradientStopCollection ID2D1GradientStopCollection_iface; diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index 4417b85..bc31f4d 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -426,12 +426,30 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateRadialGradientBrush static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateCompatibleRenderTarget(ID2D1RenderTarget *iface, const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format, - D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **render_target) + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **rt) { - FIXME("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p stub!\n", - iface, size, pixel_size, format, options, render_target); + struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface); + struct d2d_bitmap_render_target *object; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p.\n", + iface, size, pixel_size, format, options, rt); + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d2d_bitmap_render_target_init(object, render_target, size, pixel_size, + format, options))) + { + WARN("Failed to initialize render target, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + TRACE("Created render target %p.\n", object); + *rt = &object->ID2D1BitmapRenderTarget_iface; + + return S_OK; } static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateLayer(ID2D1RenderTarget *iface, @@ -602,8 +620,8 @@ static void d2d_rt_fill_geometry(struct d2d_d3d_render_target *render_target, float _12, _22, _32, pad1; } transform; - tmp_x = (2.0f * render_target->dpi_x) / (96.0f * render_target->pixel_size.width); - tmp_y = -(2.0f * render_target->dpi_y) / (96.0f * render_target->pixel_size.height); + tmp_x = (2.0f * render_target->desc.dpiX) / (96.0f * render_target->pixel_size.width); + tmp_y = -(2.0f * render_target->desc.dpiY) / (96.0f * render_target->pixel_size.height); w = render_target->drawing_state.transform; w._11 *= tmp_x; w._21 *= tmp_x; @@ -826,7 +844,7 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawText(ID2D1RenderTarget * layout_rect->right - layout_rect->left, layout_rect->bottom - layout_rect->top, &text_layout); else hr = IDWriteFactory_CreateGdiCompatibleTextLayout(dwrite_factory, string, string_len, text_format, - layout_rect->right - layout_rect->left, layout_rect->bottom - layout_rect->top, render_target->dpi_x / 96.0f, + layout_rect->right - layout_rect->left, layout_rect->bottom - layout_rect->top, render_target->desc.dpiX / 96.0f, (DWRITE_MATRIX*)&render_target->drawing_state.transform, measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL, &text_layout); IDWriteFactory_Release(dwrite_factory); if (FAILED(hr)) @@ -975,10 +993,10 @@ static void d2d_rt_draw_glyph_run_bitmap(struct d2d_d3d_render_target *render_ta bitmap_desc.pixelFormat.format = DXGI_FORMAT_A8_UNORM; bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; - bitmap_desc.dpiX = render_target->dpi_x; + bitmap_desc.dpiX = render_target->desc.dpiX; if (texture_type == DWRITE_TEXTURE_CLEARTYPE_3x1) bitmap_desc.dpiX *= 3.0f; - bitmap_desc.dpiY = render_target->dpi_y; + bitmap_desc.dpiY = render_target->desc.dpiY; if (FAILED(hr = d2d_d3d_render_target_CreateBitmap(&render_target->ID2D1RenderTarget_iface, bitmap_size, opacity_values, bitmap_size.width, &bitmap_desc, &opacity_bitmap))) { @@ -1040,7 +1058,7 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGlyphRun(ID2D1RenderTarg if (render_target->drawing_state.textAntialiasMode != D2D1_TEXT_ANTIALIAS_MODE_DEFAULT) FIXME("Ignoring text antialiasing mode %#x.\n", render_target->drawing_state.textAntialiasMode); - ppd = max(render_target->dpi_x, render_target->dpi_y) / 96.0f; + ppd = max(render_target->desc.dpiX, render_target->desc.dpiY) / 96.0f; rendering_params = render_target->text_rendering_params ? render_target->text_rendering_params : render_target->default_text_rendering_params; if (FAILED(hr = IDWriteFontFace_GetRecommendedRenderingMode(glyph_run->fontFace, glyph_run->fontEmSize, @@ -1223,8 +1241,8 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_PushAxisAlignedClip(ID2D1Ren if (antialias_mode != D2D1_ANTIALIAS_MODE_ALIASED) FIXME("Ignoring antialias_mode %#x.\n", antialias_mode); - x_scale = render_target->dpi_x / 96.0f; - y_scale = render_target->dpi_y / 96.0f; + x_scale = render_target->desc.dpiX / 96.0f; + y_scale = render_target->desc.dpiY / 96.0f; d2d_point_transform(&point, &render_target->drawing_state.transform, clip_rect->left * x_scale, clip_rect->top * y_scale); d2d_rect_set(&transformed_rect, point.x, point.y, point.x, point.y); @@ -1286,7 +1304,7 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *ifa if (color) c = *color; - if (render_target->format.alphaMode == D2D1_ALPHA_MODE_IGNORE) + if (render_target->desc.pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE) c.a = 1.0f; c.r *= c.a; c.g *= c.a; @@ -1339,7 +1357,7 @@ static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelForma TRACE("iface %p, format %p.\n", iface, format); - *format = render_target->format; + *format = render_target->desc.pixelFormat; return format; } @@ -1357,8 +1375,8 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_SetDpi(ID2D1RenderTarget *if else if (dpi_x <= 0.0f || dpi_y <= 0.0f) return; - render_target->dpi_x = dpi_x; - render_target->dpi_y = dpi_y; + render_target->desc.dpiX = dpi_x; + render_target->desc.dpiY = dpi_y; } static void STDMETHODCALLTYPE d2d_d3d_render_target_GetDpi(ID2D1RenderTarget *iface, float *dpi_x, float *dpi_y) @@ -1367,8 +1385,8 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_GetDpi(ID2D1RenderTarget *if TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y); - *dpi_x = render_target->dpi_x; - *dpi_y = render_target->dpi_y; + *dpi_x = render_target->desc.dpiX; + *dpi_y = render_target->desc.dpiY; } static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_d3d_render_target_GetSize(ID2D1RenderTarget *iface, D2D1_SIZE_F *size) @@ -1377,8 +1395,8 @@ static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_d3d_render_target_GetSize(ID2D1Render TRACE("iface %p, size %p.\n", iface, size); - size->width = render_target->pixel_size.width / (render_target->dpi_x / 96.0f); - size->height = render_target->pixel_size.height / (render_target->dpi_y / 96.0f); + size->width = render_target->pixel_size.width / (render_target->desc.dpiX / 96.0f); + size->height = render_target->pixel_size.height / (render_target->desc.dpiY / 96.0f); return size; } @@ -1541,7 +1559,7 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_GetPixelsPerDip(IDWriteTextRe TRACE("iface %p, ctx %p, ppd %p.\n", iface, ctx, ppd); - *ppd = render_target->dpi_y / 96.0f; + *ppd = render_target->desc.dpiY / 96.0f; return S_OK; } @@ -1590,7 +1608,7 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawUnderline(IDWriteTextRend iface, ctx, baseline_origin_x, baseline_origin_y, underline, effect); /* minimal thickness in DIPs that will result in at least 1 pixel thick line */ - min_thickness = 96.0f / (render_target->dpi_y * sqrtf(m->_21 * m->_21 + m->_22 * m->_22)); + min_thickness = 96.0f / (render_target->desc.dpiY * sqrtf(m->_21 * m->_21 + m->_22 * m->_22)); rect.left = baseline_origin_x; rect.top = baseline_origin_y + underline->offset; @@ -2167,7 +2185,7 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, goto err; } - render_target->format = desc->pixelFormat; + render_target->desc.pixelFormat = desc->pixelFormat; render_target->pixel_size.width = surface_desc.Width; render_target->pixel_size.height = surface_desc.Height; render_target->drawing_state.transform = identity; @@ -2179,8 +2197,8 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, goto err; } - render_target->dpi_x = dpi_x; - render_target->dpi_y = dpi_y; + render_target->desc.dpiX = dpi_x; + render_target->desc.dpiY = dpi_y; return S_OK; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 433b1a5..d9d240c 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -2993,17 +2993,8 @@ static void test_bitmap_target(void) hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt); -todo_wine ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); - if (FAILED(hr)) - { - ID2D1HwndRenderTarget_Release(hwnd_rt); - DestroyWindow(hwnd_rt_desc.hwnd); - ID2D1Factory_Release(factory); - return; - } - /* See if parent target is referenced. */ ID2D1HwndRenderTarget_AddRef(hwnd_rt); refcount = ID2D1HwndRenderTarget_Release(hwnd_rt); @@ -3059,8 +3050,8 @@ todo_wine ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1); pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(rt); - ok(pixel_size.width == ceilf(size.width * dpi2[0] / 96.0f) - && pixel_size.height == ceilf(size.height * dpi2[1] / 96.0f), "Wrong pixel size %ux%u\n", + ok(pixel_size.width == ceilf(size.width * dpi[0] / 96.0f) + && pixel_size.height == ceilf(size.height * dpi[1] / 96.0f), "Wrong pixel size %ux%u\n", pixel_size.width, pixel_size.height); dpi[0] *= (pixel_size.width / size.width) * (96.0f / dpi[0]); -- 2.9.3 From rpisl at seznam.cz Fri Oct 14 14:02:48 2016 From: rpisl at seznam.cz (Roman Pisl) Date: Fri, 14 Oct 2016 21:02:48 +0200 Subject: [PATCH] process: Make PROCESS_QUERY_LIMITED_INFORMATION sufficient for QueryFullProcessImageName(). Message-ID: <1476471768-2206-1-git-send-email-rpisl@seznam.cz> According to MSDN, QueryFullProcessImageName() should succeed when PROCESS_QUERY_LIMITED_INFORMATION is set. Signed-off-by: Roman Pisl --- dlls/kernel32/tests/process.c | 2 +- server/process.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c index 8a135ef..e470fa0 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c @@ -1953,7 +1953,7 @@ static void test_QueryFullProcessImageNameW(void) expect_eq_d(lstrlenW(buf), size); expect_eq_ws_i(buf, module_name); - hSelf = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId()); + hSelf = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, GetCurrentProcessId()); /* Real handle */ size = sizeof(buf) / sizeof(buf[0]); expect_eq_d(TRUE, pQueryFullProcessImageNameW(hSelf, 0, buf, &size)); diff --git a/server/process.c b/server/process.c index 2f2d1ad..528ec74 100644 --- a/server/process.c +++ b/server/process.c @@ -1469,7 +1469,7 @@ DECL_HANDLER(get_dll_info) { struct process *process; - if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION ))) + if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_LIMITED_INFORMATION ))) { struct process_dll *dll; -- 2.7.4 From aurimas at members.fsf.org Fri Oct 14 14:23:29 2016 From: aurimas at members.fsf.org (=?UTF-8?Q?Aurimas_Fi=c5=a1eras?=) Date: Fri, 14 Oct 2016 22:23:29 +0300 Subject: po: Update Lithuanian translation Message-ID: A non-text attachment was scrubbed... Name: 0001-po-Update-Lithuanian-translation.patch Type: text/x-patch Size: 1230 bytes Desc: not available URL: From aeikum at codeweavers.com Fri Oct 14 14:27:59 2016 From: aeikum at codeweavers.com (Andrew Eikum) Date: Fri, 14 Oct 2016 14:27:59 -0500 Subject: [PATCH] quartz: Clarify debug strings Message-ID: <20161014192759.GU7470@foghorn.codeweavers.com> Signed-off-by: Andrew Eikum --- dlls/quartz/filtergraph.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 5488afb..88af2f6 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -690,14 +690,14 @@ static HRESULT WINAPI FilterGraph2_ConnectDirect(IFilterGraph2 *iface, IPin *ppi if (FAILED(hr)) return hr; - TRACE("Filter owning first pin => %p\n", PinInfo.pFilter); + TRACE("Filter owning ppinIn(%p) => %p\n", ppinIn, PinInfo.pFilter); IBaseFilter_Release(PinInfo.pFilter); hr = IPin_QueryPinInfo(ppinOut, &PinInfo); if (FAILED(hr)) return hr; - TRACE("Filter owning second pin => %p\n", PinInfo.pFilter); + TRACE("Filter owning ppinOut(%p) => %p\n", ppinOut, PinInfo.pFilter); IBaseFilter_Release(PinInfo.pFilter); } @@ -919,14 +919,14 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut, if (FAILED(hr)) return hr; - TRACE("Filter owning first pin => %p\n", PinInfo.pFilter); + TRACE("Filter owning ppinIn(%p) => %p\n", ppinIn, PinInfo.pFilter); IBaseFilter_Release(PinInfo.pFilter); hr = IPin_QueryPinInfo(ppinOut, &PinInfo); if (FAILED(hr)) return hr; - TRACE("Filter owning second pin => %p\n", PinInfo.pFilter); + TRACE("Filter owning ppinOut(%p) => %p\n", ppinOut, PinInfo.pFilter); IBaseFilter_Release(PinInfo.pFilter); } @@ -947,6 +947,8 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut, { IPin *temp; + TRACE("Directions seem backwards, swapping pins\n"); + temp = ppinIn; ppinIn = ppinOut; ppinOut = temp; -- 2.10.0 From rpisl at seznam.cz Fri Oct 14 15:17:11 2016 From: rpisl at seznam.cz (Roman Pisl) Date: Fri, 14 Oct 2016 22:17:11 +0200 Subject: [PATCH] ws2_32: Fix condition when setting IPV6_V6ONLY in WS_bind(). Message-ID: <1476476231-3892-1-git-send-email-rpisl@seznam.cz> Setting IPV6_V6ONLY should be forced just on non in6addr_any addresses. Signed-off-by: Roman Pisl --- dlls/ws2_32/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index e8c5130..ff8179b 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3243,7 +3243,7 @@ int WINAPI WS_bind(SOCKET s, const struct WS_sockaddr* name, int namelen) #ifdef IPV6_V6ONLY const struct sockaddr_in6 *in6 = (const struct sockaddr_in6*) &uaddr; if (name->sa_family == WS_AF_INET6 && - !memcmp(&in6->sin6_addr, &in6addr_any, sizeof(struct in6_addr))) + memcmp(&in6->sin6_addr, &in6addr_any, sizeof(struct in6_addr)) != 0) { int enable = 1; if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable)) == -1) -- 2.7.4 From h.boizard at gmail.com Thu Oct 13 10:05:08 2016 From: h.boizard at gmail.com (Hadrien Boizard) Date: Thu, 13 Oct 2016 17:05:08 +0200 Subject: [PATCH] winex11.drv: Use EqualRect() instead of memcmp() to compare RECTs. Message-ID: Signed-off-by: Hadrien Boizard --- dlls/winex11.drv/window.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-winex11.drv-Use-EqualRect-instead-of-memcmp-to-compa.patch Type: text/x-patch Size: 1754 bytes Desc: not available URL: From carlo.bramix at libero.it Sat Oct 15 06:39:31 2016 From: carlo.bramix at libero.it (Carlo Bramini) Date: Sat, 15 Oct 2016 13:39:31 +0200 (CEST) Subject: [PATCH] COMDLG32: Uses SetDlgItemInt() to simplify the code. Message-ID: <1469335432.2640101476531571905.JavaMail.httpd@webmail-53.iol.local> Attached patch removes some sprintf+GetDlgItem+SetWindowText and calls SetDlgItemInt() instead. Sincerely. Signed-off-by: Carlo Bramini -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: comdlg32.txt URL: From andrey.goosev at gmail.com Sat Oct 15 15:52:24 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Sat, 15 Oct 2016 23:52:24 +0300 Subject: mscoree: Add CorIsLatestSvc function stub. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: mscoree-Add-CorIsLatestSvc-function-stub.patch Type: text/x-patch Size: 1338 bytes Desc: not available URL: From mtmkls at gmail.com Sat Oct 15 18:21:36 2016 From: mtmkls at gmail.com (=?UTF-8?q?Mikl=C3=B3s=20M=C3=A1t=C3=A9?=) Date: Sun, 16 Oct 2016 01:21:36 +0200 Subject: [PATCH 1/2] winex11: fix destroying of top-level windows v4 Message-ID: <20161015232137.3198-1-mtmkls@gmail.com> Fixes https://bugs.winehq.org/show_bug.cgi?id=40767 v2: move glXDestroyWindow before XDestroyWindow v3: fix critical section, fix command serialization with xsync now it passes the ddraw and d3d9 tests (both vanilla and csmt) v4: fix uninitialized variable, more xsync fixes (being paranoid now) Signed-off-by: Miklós Máté --- dlls/winex11.drv/opengl.c | 39 +++++++++++++++++++++++++++++++++------ dlls/winex11.drv/window.c | 1 - 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index d89a193..7b0a0cf 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1314,6 +1314,9 @@ static void free_gl_drawable( struct gl_drawable *gl ) { switch (gl->type) { + case DC_GL_WINDOW: + pglXDestroyWindow( gdi_display, gl->drawable ); + break; case DC_GL_CHILD_WIN: pglXDestroyWindow( gdi_display, gl->drawable ); XDestroyWindow( gdi_display, gl->window ); @@ -1334,21 +1337,21 @@ static void free_gl_drawable( struct gl_drawable *gl ) /*********************************************************************** * create_gl_drawable */ -static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl ) +static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl, struct x11drv_win_data *data ) { gl->drawable = 0; if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow()) /* top-level window */ { - struct x11drv_win_data *data = get_win_data( hwnd ); - if (data) { gl->type = DC_GL_WINDOW; gl->window = create_client_window( data, gl->visual ); if (gl->window) + { gl->drawable = pglXCreateWindow( gdi_display, gl->format->fbconfig, gl->window, NULL ); - release_win_data( data ); + XSync( gdi_display, False ); + } } } #ifdef SONAME_LIBXCOMPOSITE @@ -1416,6 +1419,8 @@ static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl ) static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format ) { struct gl_drawable *gl, *prev; + Window old_client_window = None; + struct x11drv_win_data *data; gl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*gl) ); /* Default GLX and WGL swap interval is 1, but in case of glXSwapIntervalSGI @@ -1435,12 +1440,19 @@ static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format ) gl->rect.right = min( max( 1, gl->rect.right ), 65535 ); gl->rect.bottom = min( max( 1, gl->rect.bottom ), 65535 ); - if (!create_gl_drawable( hwnd, gl )) + data = get_win_data( hwnd ); + if (data) { + old_client_window = data->client_window; + } + + if (!create_gl_drawable( hwnd, gl, data )) { + release_win_data( data ); XFree( gl->visual ); HeapFree( GetProcessHeap(), 0, gl ); return FALSE; } + release_win_data( data ); TRACE( "created GL drawable %lx for win %p %s\n", gl->drawable, hwnd, debugstr_fbconfig( format->fbconfig )); @@ -1452,6 +1464,10 @@ static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format ) { gl->swap_interval = prev->swap_interval; free_gl_drawable( prev ); + XSync( gdi_display, False ); + if (old_client_window) { + XDestroyWindow( data->display, old_client_window ); + } } XSaveContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char *)gl ); LeaveCriticalSection( &context_section ); @@ -1566,6 +1582,7 @@ void set_gl_drawable_parent( HWND hwnd, HWND parent ) { struct gl_drawable *gl; GLXDrawable old_drawable; + struct x11drv_win_data *data; if (!(gl = get_gl_drawable( hwnd, 0 ))) return; @@ -1575,6 +1592,7 @@ void set_gl_drawable_parent( HWND hwnd, HWND parent ) switch (gl->type) { case DC_GL_WINDOW: + pglXDestroyWindow( gdi_display, gl->drawable ); break; case DC_GL_CHILD_WIN: if (parent != GetDesktopWindow()) goto done; @@ -1590,16 +1608,20 @@ void set_gl_drawable_parent( HWND hwnd, HWND parent ) default: goto done; } + XSync( gdi_display, False ); - if (!create_gl_drawable( hwnd, gl )) + data = get_win_data( hwnd ); + if (!create_gl_drawable( hwnd, gl, data )) { XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context ); + release_win_data( data ); release_gl_drawable( gl ); XFree( gl->visual ); HeapFree( GetProcessHeap(), 0, gl ); __wine_set_pixel_format( hwnd, 0 ); return; } + release_win_data( data ); mark_drawable_dirty( old_drawable, gl->drawable ); done: @@ -1620,6 +1642,7 @@ void destroy_gl_drawable( HWND hwnd ) { XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context ); free_gl_drawable( gl ); + XSync( gdi_display, False ); } LeaveCriticalSection( &context_section ); } @@ -2386,7 +2409,10 @@ static HDC X11DRV_wglGetPbufferDCARB( struct wgl_pbuffer *object ) EnterCriticalSection( &context_section ); if (!XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&prev )) + { free_gl_drawable( prev ); + XSync( gdi_display, False ); + } XSaveContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char *)gl ); LeaveCriticalSection( &context_section ); @@ -2506,6 +2532,7 @@ static int X11DRV_wglReleasePbufferDCARB( struct wgl_pbuffer *object, HDC hdc ) { XDeleteContext( gdi_display, (XID)hdc, gl_pbuffer_context ); free_gl_drawable( gl ); + XSync( gdi_display, False ); } else hdc = 0; diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 0de7955..8768f8b 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1437,7 +1437,6 @@ Window create_client_window( struct x11drv_win_data *data, const XVisualInfo *vi if (data->client_window) { XDeleteContext( data->display, data->client_window, winContext ); - XDestroyWindow( data->display, data->client_window ); } if (data->colormap) XFreeColormap( data->display, data->colormap ); -- 2.9.3 From mtmkls at gmail.com Sat Oct 15 18:21:37 2016 From: mtmkls at gmail.com (=?UTF-8?q?Mikl=C3=B3s=20M=C3=A1t=C3=A9?=) Date: Sun, 16 Oct 2016 01:21:37 +0200 Subject: [PATCH 2/2] winex11: track glx windows per thread and destroy them on thread detach In-Reply-To: <20161015232137.3198-1-mtmkls@gmail.com> References: <20161015232137.3198-1-mtmkls@gmail.com> Message-ID: <20161015232137.3198-2-mtmkls@gmail.com> XCloseDisplay in thread_detach() closes all X windows created in that thread, but the corresponding GLX windows remain, and become zombies, because they were created with gdi_display and not data->display. If a new X window is created with the same XID, as a window that was previously destroyed like this, Mesa refuses to attach a GLX window to it because of the zombie, and set_pixel_format fails. Observed in the ddraw test, but any application that creates and destroys windows in large quantities is potentially affected by this glitch. This has been broken ever since I introduced GLX 1.3 support with commit c89dc58deb9ba74d8dcd7faf7012203cff0724a0 A cleaner approach would be to use data->display for creating GLX windows, but Mesa doesn't like it when GLX windows are bound to a context that was created with a different display connection. Also creating the contexts with data->display is not a good fix for this, because wine-csmt likes to create windows and contexts from different threads, and we are back at the same problem. The GLX specification doesn't say anything on using multiple display connections. Signed-off-by: Miklós Máté --- dlls/winex11.drv/opengl.c | 52 ++++++++++++++++++++++++++++++++++++++++++ dlls/winex11.drv/x11drv.h | 2 ++ dlls/winex11.drv/x11drv_main.c | 2 ++ 3 files changed, 56 insertions(+) diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 7b0a0cf..8d6989b 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -265,6 +265,12 @@ struct gl_drawable BOOL refresh_swap_interval; }; +struct gl_hwnd +{ + HWND hwnd; + struct list entry; +}; + enum glx_swap_control_method { GLX_SWAP_CONTROL_NONE, @@ -1419,6 +1425,8 @@ static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl, struct x11drv static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format ) { struct gl_drawable *gl, *prev; + struct gl_hwnd *glh; + struct x11drv_thread_data *thr_data; Window old_client_window = None; struct x11drv_win_data *data; @@ -1457,6 +1465,13 @@ static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format ) TRACE( "created GL drawable %lx for win %p %s\n", gl->drawable, hwnd, debugstr_fbconfig( format->fbconfig )); + thr_data = TlsGetValue( thread_data_tls_index ); + if (thr_data) + { + glh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*glh) ); + glh->hwnd = hwnd; + list_add_head( &thr_data->gl_drawables, &glh->entry ); + } XFlush( gdi_display ); EnterCriticalSection( &context_section ); @@ -1636,17 +1651,54 @@ done: void destroy_gl_drawable( HWND hwnd ) { struct gl_drawable *gl; + struct gl_hwnd *glh, *glh2; + struct x11drv_thread_data *thr_data; EnterCriticalSection( &context_section ); if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl )) { XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context ); free_gl_drawable( gl ); + + thr_data = TlsGetValue( thread_data_tls_index ); + if (thr_data) + { + LIST_FOR_EACH_ENTRY_SAFE( glh, glh2, &thr_data->gl_drawables, struct gl_hwnd, entry ) + { + if (glh->hwnd == hwnd) + { + list_remove( &glh->entry ); + HeapFree( GetProcessHeap(), 0, glh ); + } + } + } XSync( gdi_display, False ); } LeaveCriticalSection( &context_section ); } +/*********************************************************************** + * destroy_all_gl_drawables + */ +void destroy_all_gl_drawables( struct x11drv_thread_data *data ) +{ + struct gl_drawable *gl; + struct gl_hwnd *glh, *glh2; + + EnterCriticalSection( &context_section ); + LIST_FOR_EACH_ENTRY_SAFE( glh, glh2, &data->gl_drawables, struct gl_hwnd, entry ) + { + if (!XFindContext( gdi_display, (XID)(glh->hwnd), gl_hwnd_context, (char **)&gl )) + { + XDeleteContext( gdi_display, (XID)(glh->hwnd), gl_hwnd_context ); + free_gl_drawable( gl ); + } + list_remove( &glh->entry ); + HeapFree( GetProcessHeap(), 0, glh->hwnd ); + } + XSync( gdi_display, False ); + LeaveCriticalSection( &context_section ); +} /** * glxdrv_DescribePixelFormat diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 5e8d85f..1784b30 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -328,6 +328,7 @@ struct x11drv_thread_data void *xi2_devices; /* list of XInput2 devices (valid when state is enabled) */ int xi2_device_count; int xi2_core_pointer; /* XInput2 core pointer id */ + struct list gl_drawables; /* list of gl drawables created */ }; extern struct x11drv_thread_data *x11drv_init_thread_data(void) DECLSPEC_HIDDEN; @@ -567,6 +568,7 @@ extern XIC X11DRV_get_ic( HWND hwnd ) DECLSPEC_HIDDEN; extern void sync_gl_drawable( HWND hwnd, const RECT *visible_rect, const RECT *client_rect ) DECLSPEC_HIDDEN; extern void set_gl_drawable_parent( HWND hwnd, HWND parent ) DECLSPEC_HIDDEN; extern void destroy_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN; +extern void destroy_all_gl_drawables( struct x11drv_thread_data *data ) DECLSPEC_HIDDEN; extern void wait_for_withdrawn_state( HWND hwnd, BOOL set ) DECLSPEC_HIDDEN; extern Window init_clip_window(void) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 1c4ecfd..c9af34c 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -597,6 +597,7 @@ void CDECL X11DRV_ThreadDetach(void) { if (data->xim) XCloseIM( data->xim ); if (data->font_set) XFreeFontSet( data->display, data->font_set ); + destroy_all_gl_drawables( data ); XCloseDisplay( data->display ); HeapFree( GetProcessHeap(), 0, data ); /* clear data in case we get re-entered from user32 before the thread is truly dead */ @@ -661,6 +662,7 @@ struct x11drv_thread_data *x11drv_init_thread_data(void) if (TRACE_ON(synchronous)) XSynchronize( data->display, True ); set_queue_display_fd( data->display ); + list_init( &data->gl_drawables ); TlsSetValue( thread_data_tls_index, data ); if (use_xim) X11DRV_SetupXIM(); -- 2.9.3 From sebastian at fds-team.de Sun Oct 16 01:48:55 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Sun, 16 Oct 2016 08:48:55 +0200 Subject: [1/5] ntoskrnl.exe: Defer deallocation of in_buff in dispatch_ioctl. Message-ID: Signed-off-by: Sebastian Lackner --- Otherwise the caller might try to reuse the released buffer in case of a failure. dlls/ntoskrnl.exe/ntoskrnl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 428e700..3c18ee6 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -417,6 +417,7 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG { IRP *irp; void *out_buff = NULL; + void *to_free = NULL; DEVICE_OBJECT *device; FILE_OBJECT *file = wine_server_get_ptr( params->ioctl.file ); @@ -435,7 +436,7 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG if ((params->ioctl.code & 3) == METHOD_BUFFERED) { memcpy( out_buff, in_buff, in_size ); - HeapFree( GetProcessHeap(), 0, in_buff ); + to_free = in_buff; in_buff = out_buff; } } @@ -455,6 +456,7 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG irp->Flags |= IRP_DEALLOCATE_BUFFER; /* deallocate in_buff */ dispatch_irp( device, irp, irp_handle ); + HeapFree( GetProcessHeap(), 0, to_free ); return STATUS_SUCCESS; } -- 2.9.0 From sebastian at fds-team.de Sun Oct 16 01:51:06 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Sun, 16 Oct 2016 08:51:06 +0200 Subject: [2/5] ntoskrnl.exe: Add support for METHOD_IN_DIRECT/METHOD_OUT_DIRECT ioctls. Message-ID: Signed-off-by: Sebastian Lackner --- For METHOD_IN_DIRECT and METHOD_OUT_DIRECT the output buffer is not only used for output, it can also contain input data. This is the case for some HID ioctls for example. To be compatible with such ioctls, we have to transfer the output buffer aswell (even if it might contain garbage in some cases). This patch also improves handling for METHOD_NEITHER, where the handling is completely up to the driver. To avoid complexity in the wineserver, this patch transfers (if necessary) both buffers as a big chunk of data. For processing it is splitted again in ntoskrnl. Please note that the only ioctl with input buffer directly implemented in wineserver is FSCTL_PIPE_WAIT, which is METHOD_BUFFERED and does not have to be modified. dlls/ntdll/file.c | 2 ++ dlls/ntoskrnl.exe/ntoskrnl.c | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 7fbde50..cefc1dd 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -1561,6 +1561,8 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event, req->async.event = wine_server_obj_handle( event ); req->async.cvalue = cvalue; wine_server_add_data( req, in_buffer, in_size ); + if ((code & 3) != METHOD_BUFFERED) + wine_server_add_data( req, out_buffer, out_size ); wine_server_set_reply( req, out_buffer, out_size ); status = wine_server_call( req ); wait_handle = wine_server_ptr_handle( reply->wait ); diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 3c18ee6..912d084 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -428,17 +428,27 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG TRACE( "ioctl %x device %p file %p in_size %u out_size %u\n", params->ioctl.code, device, file, in_size, out_size ); - if ((params->ioctl.code & 3) == METHOD_BUFFERED) out_size = max( in_size, out_size ); - if (out_size) { - if (!(out_buff = HeapAlloc( GetProcessHeap(), 0, out_size ))) return STATUS_NO_MEMORY; - if ((params->ioctl.code & 3) == METHOD_BUFFERED) + if ((params->ioctl.code & 3) != METHOD_BUFFERED) + { + if (in_size < out_size) return STATUS_INVALID_DEVICE_REQUEST; + in_size -= out_size; + if (!(out_buff = HeapAlloc( GetProcessHeap(), 0, out_size ))) return STATUS_NO_MEMORY; + memcpy( out_buff, (char *)in_buff + in_size, out_size ); + } + else if (out_size > in_size) { + if (!(out_buff = HeapAlloc( GetProcessHeap(), 0, out_size ))) return STATUS_NO_MEMORY; memcpy( out_buff, in_buff, in_size ); to_free = in_buff; in_buff = out_buff; } + else + { + out_buff = in_buff; + out_size = in_size; + } } irp = IoBuildDeviceIoControlRequest( params->ioctl.code, device, in_buff, in_size, out_buff, out_size, @@ -449,6 +459,9 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG return STATUS_NO_MEMORY; } + if (out_size && (params->ioctl.code & 3) != METHOD_BUFFERED) + HeapReAlloc( GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, in_buff, in_size ); + irp->Tail.Overlay.OriginalFileObject = file; irp->RequestorMode = UserMode; irp->AssociatedIrp.SystemBuffer = in_buff; -- 2.9.0 From sebastian at fds-team.de Sun Oct 16 01:53:29 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Sun, 16 Oct 2016 08:53:29 +0200 Subject: [3/5] ntoskrnl.exe: Use MmInitializeMdl in IoAllocateMdl. Message-ID: <7e39e9c9-3fa8-ae4f-a338-ad22a940e088@fds-team.de> Signed-off-by: Sebastian Lackner --- Please note that the existing logic to compute nb_pages is flawed when length == 0 and address is a multiple of the page size. Process is not explicitly assigned because the pages are not locked yet. It is also missing in the MmInitializeMdl macro from the Windows header files. dlls/ntoskrnl.exe/ntoskrnl.c | 19 ++++--------------- include/ddk/wdm.h | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 912d084..eac81f7 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -744,31 +744,20 @@ PVOID WINAPI IoAllocateErrorLogEntry( PVOID IoObject, UCHAR EntrySize ) */ PMDL WINAPI IoAllocateMdl( PVOID va, ULONG length, BOOLEAN secondary, BOOLEAN charge_quota, IRP *irp ) { + SIZE_T mdl_size; PMDL mdl; - ULONG_PTR address = (ULONG_PTR)va; - ULONG_PTR page_address; - SIZE_T nb_pages, mdl_size; TRACE("(%p, %u, %i, %i, %p)\n", va, length, secondary, charge_quota, irp); if (charge_quota) FIXME("Charge quota is not yet supported\n"); - /* FIXME: We suppose that page size is 4096 */ - page_address = address & ~(4096 - 1); - nb_pages = (((address + length - 1) & ~(4096 - 1)) - page_address) / 4096 + 1; - - mdl_size = sizeof(MDL) + nb_pages * sizeof(PVOID); - - mdl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mdl_size); + mdl_size = sizeof(MDL) + sizeof(PFN_NUMBER) * ADDRESS_AND_SIZE_TO_SPAN_PAGES(va, length); + mdl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, mdl_size ); if (!mdl) return NULL; - mdl->Size = mdl_size; - mdl->Process = NULL; /* FIXME: IoGetCurrentProcess */ - mdl->StartVa = (PVOID)page_address; - mdl->ByteCount = length; - mdl->ByteOffset = address - page_address; + MmInitializeMdl( mdl, va, length ); if (!irp) return mdl; diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 3e93469..61de490 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -28,6 +28,15 @@ #define POINTER_ALIGNMENT #endif +/* FIXME: We suppose that page size is 4096 */ +#define PAGE_SIZE 0x1000 +#define PAGE_SHIFT 12 + +#define BYTE_OFFSET(va) ((ULONG)((ULONG_PTR)(va) & (PAGE_SIZE - 1))) +#define PAGE_ALIGN(va) ((PVOID)((ULONG_PTR)(va) & ~(PAGE_SIZE - 1))) +#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(va, length) \ + ((BYTE_OFFSET(va) + ((SIZE_T)(length)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT) + typedef LONG KPRIORITY; typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK; @@ -1035,6 +1044,17 @@ typedef struct _MDL { } MDL, *PMDL; typedef MDL *PMDLX; +typedef ULONG PFN_NUMBER, *PPFN_NUMBER; + +static inline void MmInitializeMdl(MDL *mdl, void *va, SIZE_T length) +{ + mdl->Next = NULL; + mdl->Size = sizeof(MDL) + sizeof(PFN_NUMBER) * ADDRESS_AND_SIZE_TO_SPAN_PAGES(va, length); + mdl->MdlFlags = 0; + mdl->StartVa = (void *)PAGE_ALIGN(va); + mdl->ByteOffset = BYTE_OFFSET(va); + mdl->ByteCount = length; +} typedef struct _KTIMER { DISPATCHER_HEADER Header; -- 2.9.0 From sebastian at fds-team.de Sun Oct 16 01:57:21 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Sun, 16 Oct 2016 08:57:21 +0200 Subject: [4/5] ntoskrnl.exe: Explicitly set MappedSystemVa for MDLs. Message-ID: Signed-off-by: Sebastian Lackner --- We do not have a general mechanism to lock pages yet. For now, manually set MappedSystemVa and the MDL_MAPPED_TO_SYSTEM_VA flag. This patch also adds the definition of MmGetSystemAddressForMdlSafe() which is how drivers should access the buffer. After this patch, the following test executable which uses a METHOD_OUT_DIRECT ioctl should work fine in Wine (produce identical results): https://newtestbot.winehq.org/JobDetails.pl?Key=26184 dlls/ntoskrnl.exe/ntoskrnl.c | 26 ++++++++++++++++++++++++-- include/ddk/wdm.h | 9 +++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index eac81f7..854d68d 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -820,6 +820,7 @@ PIRP WINAPI IoBuildDeviceIoControlRequest( ULONG code, PDEVICE_OBJECT device, { PIRP irp; PIO_STACK_LOCATION irpsp; + MDL *mdl; TRACE( "%x, %p, %p, %u, %p, %u, %u, %p, %p\n", code, device, in_buff, in_len, out_buff, out_len, internal, event, iosb ); @@ -847,7 +848,16 @@ PIRP WINAPI IoBuildDeviceIoControlRequest( ULONG code, PDEVICE_OBJECT device, case METHOD_IN_DIRECT: case METHOD_OUT_DIRECT: irp->AssociatedIrp.SystemBuffer = in_buff; - IoAllocateMdl( out_buff, out_len, FALSE, FALSE, irp ); + + mdl = IoAllocateMdl( out_buff, out_len, FALSE, FALSE, irp ); + if (!mdl) + { + IoFreeIrp( irp ); + return NULL; + } + + mdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA; + mdl->MappedSystemVa = out_buff; break; case METHOD_NEITHER: irpsp->Parameters.DeviceIoControl.Type3InputBuffer = in_buff; @@ -882,7 +892,19 @@ PIRP WINAPI IoBuildSynchronousFsdRequest(ULONG majorfunc, PDEVICE_OBJECT device, irpsp->CompletionRoutine = NULL; irp->AssociatedIrp.SystemBuffer = buffer; - if (device->Flags & DO_DIRECT_IO) IoAllocateMdl( buffer, length, FALSE, FALSE, irp ); + + if (device->Flags & DO_DIRECT_IO) + { + MDL *mdl = IoAllocateMdl( buffer, length, FALSE, FALSE, irp ); + if (!mdl) + { + IoFreeIrp( irp ); + return NULL; + } + + mdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA; + mdl->MappedSystemVa = buffer; + } switch (majorfunc) { diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 61de490..3dda667 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1305,8 +1305,17 @@ PVOID WINAPI MmAllocateContiguousMemory(SIZE_T,PHYSICAL_ADDRESS); PVOID WINAPI MmAllocateNonCachedMemory(SIZE_T); PMDL WINAPI MmAllocatePagesForMdl(PHYSICAL_ADDRESS,PHYSICAL_ADDRESS,PHYSICAL_ADDRESS,SIZE_T); void WINAPI MmFreeNonCachedMemory(PVOID,SIZE_T); +PVOID WINAPI MmMapLockedPagesSpecifyCache(PMDL,KPROCESSOR_MODE,MEMORY_CACHING_TYPE,PVOID,ULONG,ULONG); MM_SYSTEMSIZE WINAPI MmQuerySystemSize(void); +static inline void *MmGetSystemAddressForMdlSafe(MDL *mdl, ULONG priority) +{ + if (mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL)) + return mdl->MappedSystemVa; + else + return MmMapLockedPagesSpecifyCache(mdl, KernelMode, MmCached, NULL, FALSE, priority); +} + void WINAPI ObDereferenceObject(void*); NTSTATUS WINAPI ObReferenceObjectByHandle(HANDLE,ACCESS_MASK,POBJECT_TYPE,KPROCESSOR_MODE,PVOID*,POBJECT_HANDLE_INFORMATION); NTSTATUS WINAPI ObReferenceObjectByName(UNICODE_STRING*,ULONG,ACCESS_STATE*,ACCESS_MASK,POBJECT_TYPE,KPROCESSOR_MODE,void*,void**); -- 2.9.0 From sebastian at fds-team.de Sun Oct 16 01:59:23 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Sun, 16 Oct 2016 08:59:23 +0200 Subject: [5/5] hidclass.sys: Use MmGetSystemAddressForMdlSafe to access MDL data. Message-ID: Signed-off-by: Sebastian Lackner --- Manual computations with StartVa should be avoided. dlls/hidclass.sys/device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index d2a4710..189cd2e 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -419,7 +419,7 @@ static NTSTATUS handle_minidriver_string(DEVICE_OBJECT *device, IRP *irp, SHORT if (status == STATUS_SUCCESS) { - WCHAR *out_buffer = (WCHAR*)(((BYTE*)irp->MdlAddress->StartVa) + irp->MdlAddress->ByteOffset); + WCHAR *out_buffer = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority); int length = irpsp->Parameters.DeviceIoControl.OutputBufferLength/sizeof(WCHAR); TRACE("got string %s from minidriver\n",debugstr_w(buffer)); lstrcpynW(out_buffer, buffer, length); @@ -440,7 +440,7 @@ static NTSTATUS HID_get_feature(DEVICE_OBJECT *device, IRP *irp) irp->IoStatus.Information = 0; - out_buffer = (((BYTE*)irp->MdlAddress->StartVa) + irp->MdlAddress->ByteOffset); + out_buffer = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority); TRACE_(hid_report)("Device %p Buffer length %i Buffer %p\n", device, irpsp->Parameters.DeviceIoControl.OutputBufferLength, out_buffer); len = sizeof(*packet) + irpsp->Parameters.DeviceIoControl.OutputBufferLength; @@ -569,7 +569,7 @@ NTSTATUS WINAPI HID_Device_ioctl(DEVICE_OBJECT *device, IRP *irp) case IOCTL_HID_GET_INPUT_REPORT: { HID_XFER_PACKET packet; - BYTE* buffer = ((BYTE*)irp->MdlAddress->StartVa) + irp->MdlAddress->ByteOffset; + BYTE *buffer = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority); if (extension->preparseData->InputReports[0].reportID) packet.reportId = buffer[0]; -- 2.9.0 From jre.winesim at gmail.com Sun Oct 16 05:57:36 2016 From: jre.winesim at gmail.com (Jens Reyer) Date: Sun, 16 Oct 2016 12:57:36 +0200 Subject: libs/wine: give user an error message if WINEARCH is not win32/win64 (try 2) In-Reply-To: References: Message-ID: <2e39a6af-c4d3-3ad6-151a-a5b19866acc3@gmail.com> Signed-off-by: Jens Reyer --- lgtm and tested successfully. Thanks! From mtmkls at gmail.com Sun Oct 16 10:59:06 2016 From: mtmkls at gmail.com (=?UTF-8?q?Mikl=C3=B3s=20M=C3=A1t=C3=A9?=) Date: Sun, 16 Oct 2016 17:59:06 +0200 Subject: [PATCH] winex11: fix destroying of top-level windows v5 Message-ID: <20161016155906.28152-1-mtmkls@gmail.com> Fixes https://bugs.winehq.org/show_bug.cgi?id=40767 v2: move glXDestroyWindow before XDestroyWindow v3: fix critical section, fix command serialization with xsync now it passes the ddraw and d3d9 tests (both vanilla and csmt) v4: fix uninitialized variable, more xsync fixes (being paranoid now) v5: remove the incorrect xsync calls added by v4, fix SetParent Signed-off-by: Miklós Máté --- I shouldn't have sent out v4 after 1AM, sorry. dlls/winex11.drv/opengl.c | 35 +++++++++++++++++++++++++++++------ dlls/winex11.drv/window.c | 2 +- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index d89a193..ae2e231 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1314,6 +1314,9 @@ static void free_gl_drawable( struct gl_drawable *gl ) { switch (gl->type) { + case DC_GL_WINDOW: + pglXDestroyWindow( gdi_display, gl->drawable ); + break; case DC_GL_CHILD_WIN: pglXDestroyWindow( gdi_display, gl->drawable ); XDestroyWindow( gdi_display, gl->window ); @@ -1334,21 +1337,21 @@ static void free_gl_drawable( struct gl_drawable *gl ) /*********************************************************************** * create_gl_drawable */ -static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl ) +static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl, struct x11drv_win_data *data ) { gl->drawable = 0; if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow()) /* top-level window */ { - struct x11drv_win_data *data = get_win_data( hwnd ); - if (data) { gl->type = DC_GL_WINDOW; gl->window = create_client_window( data, gl->visual ); if (gl->window) + { gl->drawable = pglXCreateWindow( gdi_display, gl->format->fbconfig, gl->window, NULL ); - release_win_data( data ); + XSync( gdi_display, False ); + } } } #ifdef SONAME_LIBXCOMPOSITE @@ -1416,6 +1419,8 @@ static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl ) static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format ) { struct gl_drawable *gl, *prev; + Window old_client_window = None; + struct x11drv_win_data *data; gl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*gl) ); /* Default GLX and WGL swap interval is 1, but in case of glXSwapIntervalSGI @@ -1435,12 +1440,19 @@ static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format ) gl->rect.right = min( max( 1, gl->rect.right ), 65535 ); gl->rect.bottom = min( max( 1, gl->rect.bottom ), 65535 ); - if (!create_gl_drawable( hwnd, gl )) + data = get_win_data( hwnd ); + if (data) { + old_client_window = data->client_window; + } + + if (!create_gl_drawable( hwnd, gl, data )) { + release_win_data( data ); XFree( gl->visual ); HeapFree( GetProcessHeap(), 0, gl ); return FALSE; } + release_win_data( data ); TRACE( "created GL drawable %lx for win %p %s\n", gl->drawable, hwnd, debugstr_fbconfig( format->fbconfig )); @@ -1452,6 +1464,10 @@ static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format ) { gl->swap_interval = prev->swap_interval; free_gl_drawable( prev ); + XSync( gdi_display, False ); + if (old_client_window) { + XDestroyWindow( data->display, old_client_window ); + } } XSaveContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char *)gl ); LeaveCriticalSection( &context_section ); @@ -1566,6 +1582,7 @@ void set_gl_drawable_parent( HWND hwnd, HWND parent ) { struct gl_drawable *gl; GLXDrawable old_drawable; + struct x11drv_win_data *data; if (!(gl = get_gl_drawable( hwnd, 0 ))) return; @@ -1575,6 +1592,7 @@ void set_gl_drawable_parent( HWND hwnd, HWND parent ) switch (gl->type) { case DC_GL_WINDOW: + pglXDestroyWindow( gdi_display, gl->drawable ); break; case DC_GL_CHILD_WIN: if (parent != GetDesktopWindow()) goto done; @@ -1590,16 +1608,20 @@ void set_gl_drawable_parent( HWND hwnd, HWND parent ) default: goto done; } + XSync( gdi_display, False ); - if (!create_gl_drawable( hwnd, gl )) + data = get_win_data( hwnd ); + if (!create_gl_drawable( hwnd, gl, data )) { XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context ); + release_win_data( data ); release_gl_drawable( gl ); XFree( gl->visual ); HeapFree( GetProcessHeap(), 0, gl ); __wine_set_pixel_format( hwnd, 0 ); return; } + release_win_data( data ); mark_drawable_dirty( old_drawable, gl->drawable ); done: @@ -1620,6 +1642,7 @@ void destroy_gl_drawable( HWND hwnd ) { XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context ); free_gl_drawable( gl ); + XSync( gdi_display, False ); } LeaveCriticalSection( &context_section ); } diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 0de7955..0f23c72 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1437,7 +1437,6 @@ Window create_client_window( struct x11drv_win_data *data, const XVisualInfo *vi if (data->client_window) { XDeleteContext( data->display, data->client_window, winContext ); - XDestroyWindow( data->display, data->client_window ); } if (data->colormap) XFreeColormap( data->display, data->colormap ); @@ -2169,6 +2168,7 @@ void CDECL X11DRV_SetParent( HWND hwnd, HWND parent, HWND old_parent ) if (old_parent == GetDesktopWindow()) { /* destroy the old X windows */ + destroy_gl_drawable( hwnd ); destroy_whole_window( data, FALSE ); data->managed = FALSE; } -- 2.9.3 From andrey.goosev at gmail.com Sun Oct 16 11:46:46 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Sun, 16 Oct 2016 19:46:46 +0300 Subject: wpc: Fix TRACE for WindowsParentalControls_CreateInstance. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: wpc-Fix-TRACE-for-WindowsParentalControls_CreateInst.patch Type: text/x-patch Size: 962 bytes Desc: not available URL: From nsivov at codeweavers.com Sun Oct 16 13:05:33 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Sun, 16 Oct 2016 21:05:33 +0300 Subject: [PATCH] po: Update Russian translation Message-ID: <20161016180533.7345-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- po/ru.po | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/po/ru.po b/po/ru.po index 62cf1f6..a834c13 100644 --- a/po/ru.po +++ b/po/ru.po @@ -5,14 +5,14 @@ msgstr "" "Project-Id-Version: Wine\n" "Report-Msgid-Bugs-To: http://bugs.winehq.org\n" "POT-Creation-Date: N/A\n" -"PO-Revision-Date: 2016-07-15 23:49+0300\n" +"PO-Revision-Date: 2016-10-14 22:09+0300\n" "Last-Translator: Nikolay Sivov \n" "Language-Team: Russian\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.8\n" +"X-Generator: Poedit 1.8.9\n" #: appwiz.rc:58 msgid "Install/Uninstall" @@ -14584,36 +14584,32 @@ msgid "F&ormat" msgstr "Фор&мат" #: wordpad.rc:85 -#, fuzzy -#| msgid "&List" msgid "&Lists" -msgstr "&Список" +msgstr "&Списки" #: wordpad.rc:87 wordpad.rc:116 msgid "&Bullet points" msgstr "&Маркер" #: wordpad.rc:88 -#, fuzzy -#| msgid "CRL Number" msgid "Numbers" -msgstr "Номер CRL" +msgstr "Числа" #: wordpad.rc:89 msgid "Letters - lower case" -msgstr "" +msgstr "Буквы - строчные" #: wordpad.rc:90 msgid "Letters - upper case" -msgstr "" +msgstr "Буквы - прописные" #: wordpad.rc:91 msgid "Roman numerals - lower case" -msgstr "" +msgstr "Римские числа - строчные" #: wordpad.rc:92 msgid "Roman numerals - upper case" -msgstr "" +msgstr "Римские числа - прописные" #: wordpad.rc:94 wordpad.rc:117 msgid "&Paragraph..." -- 2.9.3 From jkucia at codeweavers.com Sun Oct 16 14:46:44 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Sun, 16 Oct 2016 21:46:44 +0200 Subject: [PATCH 1/6] wined3d: Let buffer_direct_upload() invalidate STATE_INDEXBUFFER if needed. Message-ID: <1476647209-11162-1-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index b50132a..8943144 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -668,15 +668,13 @@ drop_query: } /* The caller provides a GL context */ -static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info, DWORD flags) +static void buffer_direct_upload(struct wined3d_buffer *This, struct wined3d_context *context, DWORD flags) { + const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int start, len; BYTE *map; - UINT start, len; - /* This potentially invalidates the element array buffer binding, but the - * caller always takes care of this. */ - GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object)); - checkGLcall("glBindBuffer"); + buffer_bind(This, context); if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) { GLbitfield mapflags; @@ -686,7 +684,7 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined else if (!(flags & WINED3D_BUFFER_SYNC)) mapflags |= GL_MAP_UNSYNCHRONIZED_BIT; map = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0, - This->resource.size, mapflags)); + This->resource.size, mapflags)); checkGLcall("glMapBufferRange"); } else @@ -867,12 +865,9 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte /* Nothing to do because we locked directly into the vbo */ if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) - { return; - } - - buffer_direct_upload(buffer, gl_info, flags); + buffer_direct_upload(buffer, context, flags); return; } -- 2.7.3 From jkucia at codeweavers.com Sun Oct 16 14:46:45 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Sun, 16 Oct 2016 21:46:45 +0200 Subject: [PATCH 2/6] wined3d: Clean up buffer_internal_preload(). In-Reply-To: <1476647209-11162-1-git-send-email-jkucia@codeweavers.com> References: <1476647209-11162-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476647209-11162-2-git-send-email-jkucia@codeweavers.com> The conversion should never be performed for buffers with buffer_type_hint other than GL_ARRAY_BUFFER. Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 8943144..49bed64 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -422,7 +422,7 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This, const struct wined3d_s return ret; } -static inline void fixup_d3dcolor(DWORD *dst_color) +static inline unsigned int fixup_d3dcolor(DWORD *dst_color) { DWORD src_color = *dst_color; @@ -439,9 +439,11 @@ static inline void fixup_d3dcolor(DWORD *dst_color) *dst_color |= (src_color & 0xff00ff00u); /* Alpha Green */ *dst_color |= (src_color & 0x00ff0000u) >> 16; /* Red */ *dst_color |= (src_color & 0x000000ffu) << 16; /* Blue */ + + return sizeof(*dst_color); } -static inline void fixup_transformed_pos(float *p) +static inline unsigned int fixup_transformed_pos(float *p) { /* rhw conversion like in position_float4(). */ if (p[3] != 1.0f && p[3] != 0.0f) @@ -452,6 +454,8 @@ static inline void fixup_transformed_pos(float *p) p[2] *= w; p[3] = w; } + + return 4 * sizeof(*p); } /* Context activation is done by the caller. */ @@ -741,10 +745,8 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte { DWORD flags = buffer->flags & (WINED3D_BUFFER_SYNC | WINED3D_BUFFER_DISCARD); const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_device *device = buffer->resource.device; - UINT start, end, len, vertices; + unsigned int i, j, start, end, len, vertex_count; BOOL decl_changed = FALSE; - unsigned int i, j; BYTE *data; TRACE("buffer %p.\n", buffer); @@ -851,9 +853,6 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte } } - if (buffer->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) - device_invalidate_state(device, STATE_INDEXBUFFER); - if (!buffer->conversion_map) { /* That means that there is nothing to fixup. Just upload from @@ -871,17 +870,23 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte return; } - if(!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) - { + /* This would potentially invalidate the element array buffer binding. */ + if (buffer->buffer_type_hint != GL_ARRAY_BUFFER) + ERR("Converting data in non-vertex buffer.\n"); + + if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) buffer_get_sysmem(buffer, context); - } /* Now for each vertex in the buffer that needs conversion */ - vertices = buffer->resource.size / buffer->stride; + vertex_count = buffer->resource.size / buffer->stride; - data = HeapAlloc(GetProcessHeap(), 0, buffer->resource.size); + if (!(data = HeapAlloc(GetProcessHeap(), 0, buffer->resource.size))) + { + ERR("Out of memory.\n"); + return; + } - while(buffer->modified_areas) + while (buffer->modified_areas) { buffer->modified_areas--; start = buffer->maps[buffer->modified_areas].offset; @@ -889,27 +894,25 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte end = start + len; memcpy(data + start, (BYTE *)buffer->resource.heap_memory + start, end - start); - for (i = start / buffer->stride; i < min((end / buffer->stride) + 1, vertices); ++i) + for (i = start / buffer->stride; i < min((end / buffer->stride) + 1, vertex_count); ++i) { - for (j = 0; j < buffer->stride; ++j) + for (j = 0; j < buffer->stride;) { switch (buffer->conversion_map[j]) { case CONV_NONE: /* Done already */ - j += 3; + j += sizeof(DWORD); break; case CONV_D3DCOLOR: - fixup_d3dcolor((DWORD *) (data + i * buffer->stride + j)); - j += 3; + j += fixup_d3dcolor((DWORD *) (data + i * buffer->stride + j)); break; - case CONV_POSITIONT: - fixup_transformed_pos((float *) (data + i * buffer->stride + j)); - j += 15; + j += fixup_transformed_pos((float *) (data + i * buffer->stride + j)); break; default: - FIXME("Unimplemented conversion %d in shifted conversion\n", buffer->conversion_map[j]); + FIXME("Unimplemented conversion %d in shifted conversion.\n", buffer->conversion_map[j]); + ++j; } } } -- 2.7.3 From jkucia at codeweavers.com Sun Oct 16 14:46:46 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Sun, 16 Oct 2016 21:46:46 +0200 Subject: [PATCH 3/6] wined3d: Rename buffer_internal_preload() to wined3d_buffer_load(). In-Reply-To: <1476647209-11162-1-git-send-email-jkucia@codeweavers.com> References: <1476647209-11162-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476647209-11162-3-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 4 ++-- dlls/wined3d/context.c | 8 ++++---- dlls/wined3d/wined3d_private.h | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 49bed64..ae835be 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -740,7 +740,7 @@ void buffer_mark_used(struct wined3d_buffer *buffer) } /* Context activation is done by the caller. */ -void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, +void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_state *state) { DWORD flags = buffer->flags & (WINED3D_BUFFER_SYNC | WINED3D_BUFFER_DISCARD); @@ -1219,7 +1219,7 @@ static void buffer_resource_preload(struct wined3d_resource *resource) struct wined3d_context *context; context = context_acquire(resource->device, NULL); - buffer_internal_preload(buffer_from_resource(resource), context, NULL); + wined3d_buffer_load(buffer_from_resource(resource), context, NULL); context_release(context); } diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 87d417c..38e081b 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -3200,7 +3200,7 @@ static void context_update_stream_info(struct wined3d_context *context, const st } else { - buffer_internal_preload(buffer, context, state); + wined3d_buffer_load(buffer, context, state); buffer_get_memory(buffer, context, &data); element->data.buffer_object = data.buffer_object; element->data.addr += (ULONG_PTR)data.addr; @@ -3304,7 +3304,7 @@ static void context_load_shader_resources(struct wined3d_context *context, const for (j = 0; j < WINED3D_MAX_CBS; ++j) { if (state->cb[i][j]) - buffer_internal_preload(state->cb[i][j], context, state); + wined3d_buffer_load(state->cb[i][j], context, state); } for (j = 0; j < shader->reg_maps.sampler_map.count; ++j) @@ -3318,7 +3318,7 @@ static void context_load_shader_resources(struct wined3d_context *context, const } if (view->resource->type == WINED3D_RTYPE_BUFFER) - buffer_internal_preload(buffer_from_resource(view->resource), context, state); + wined3d_buffer_load(buffer_from_resource(view->resource), context, state); else wined3d_texture_load(texture_from_resource(view->resource), context, FALSE); } @@ -3430,7 +3430,7 @@ BOOL context_apply_draw_state(struct wined3d_context *context, if (state->index_buffer) { if (context->stream_info.all_vbo) - buffer_internal_preload(state->index_buffer, context, state); + wined3d_buffer_load(state->index_buffer, context, state); else buffer_get_sysmem(state->index_buffer, context); } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 4326bee..5e4b072 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3181,9 +3181,9 @@ static inline struct wined3d_buffer *buffer_from_resource(struct wined3d_resourc void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *context, struct wined3d_bo_address *data) DECLSPEC_HIDDEN; BYTE *buffer_get_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) DECLSPEC_HIDDEN; -void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, - const struct wined3d_state *state) DECLSPEC_HIDDEN; void buffer_mark_used(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; +void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *context, + const struct wined3d_state *state) DECLSPEC_HIDDEN; HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_offset, struct wined3d_buffer *src_buffer, unsigned int src_offset, unsigned int size) DECLSPEC_HIDDEN; HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, -- 2.7.3 From jkucia at codeweavers.com Sun Oct 16 14:46:47 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Sun, 16 Oct 2016 21:46:47 +0200 Subject: [PATCH 4/6] wined3d: Rename buffer_get_sysmem() to wined3d_buffer_load_sysmem(). In-Reply-To: <1476647209-11162-1-git-send-email-jkucia@codeweavers.com> References: <1476647209-11162-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476647209-11162-4-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 8 ++++---- dlls/wined3d/context.c | 4 ++-- dlls/wined3d/device.c | 2 +- dlls/wined3d/drawprim.c | 6 +++--- dlls/wined3d/state.c | 2 +- dlls/wined3d/wined3d_private.h | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index ae835be..b6338d1 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -493,7 +493,7 @@ ULONG CDECL wined3d_buffer_incref(struct wined3d_buffer *buffer) } /* Context activation is done by the caller. */ -BYTE *buffer_get_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) +BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -528,7 +528,7 @@ static void buffer_unload(struct wined3d_resource *resource) /* Download the buffer, but don't permanently enable double buffering */ if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) { - buffer_get_sysmem(buffer, context); + wined3d_buffer_load_sysmem(buffer, context); buffer->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER; } @@ -875,7 +875,7 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context * ERR("Converting data in non-vertex buffer.\n"); if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) - buffer_get_sysmem(buffer, context); + wined3d_buffer_load_sysmem(buffer, context); /* Now for each vertex in the buffer that needs conversion */ vertex_count = buffer->resource.size / buffer->stride; @@ -1010,7 +1010,7 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI else { TRACE("Falling back to doublebuffered operation.\n"); - buffer_get_sysmem(buffer, context); + wined3d_buffer_load_sysmem(buffer, context); } TRACE("New pointer is %p.\n", buffer->resource.heap_memory); buffer->map_ptr = NULL; diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 38e081b..1ca12bc 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -3194,7 +3194,7 @@ static void context_update_stream_info(struct wined3d_context *context, const st WARN_(d3d_perf)("load_base_vertex_index is < 0 (%d), not using VBOs.\n", state->load_base_vertex_index); element->data.buffer_object = 0; - element->data.addr += (ULONG_PTR)buffer_get_sysmem(buffer, context); + element->data.addr += (ULONG_PTR)wined3d_buffer_load_sysmem(buffer, context); if ((UINT_PTR)element->data.addr < -state->load_base_vertex_index * element->stride) FIXME("System memory vertex data load offset is negative!\n"); } @@ -3432,7 +3432,7 @@ BOOL context_apply_draw_state(struct wined3d_context *context, if (context->stream_info.all_vbo) wined3d_buffer_load(state->index_buffer, context, state); else - buffer_get_sysmem(state->index_buffer, context); + wined3d_buffer_load_sysmem(state->index_buffer, context); } for (i = 0; i < context->numDirtyEntries; ++i) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 9bf6042..89b781c 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3174,7 +3174,7 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, e = &stream_info.elements[i]; buffer = state->streams[e->stream_idx].buffer; e->data.buffer_object = 0; - e->data.addr += (ULONG_PTR)buffer_get_sysmem(buffer, context); + e->data.addr += (ULONG_PTR)wined3d_buffer_load_sysmem(buffer, context); if (buffer->buffer_object) { GL_EXTCALL(glDeleteBuffers(1, &buffer->buffer_object)); diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index e5b30db..4833845 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -135,7 +135,7 @@ static void draw_primitive_arrays(struct wined3d_context *context, const struct element = &si->elements[element_idx]; ptr = element->data.addr + element->stride * i; if (element->data.buffer_object) - ptr += (ULONG_PTR)buffer_get_sysmem(state->streams[element->stream_idx].buffer, context); + ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(state->streams[element->stream_idx].buffer, context); ops->generic[element->format->emit_idx](element_idx, ptr); } @@ -201,7 +201,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const * supported or other reason), or with user pointer drawing idx_data * will be non-NULL. */ if (idx_size && !idx_data) - idx_data = buffer_get_sysmem(state->index_buffer, context); + idx_data = wined3d_buffer_load_sysmem(state->index_buffer, context); ops = &d3d_info->ffp_attrib_ops; @@ -402,7 +402,7 @@ static void remove_vbos(struct wined3d_context *context, { struct wined3d_buffer *vb = state->streams[e->stream_idx].buffer; e->data.buffer_object = 0; - e->data.addr = (BYTE *)((ULONG_PTR)e->data.addr + (ULONG_PTR)buffer_get_sysmem(vb, context)); + e->data.addr = (BYTE *)((ULONG_PTR)e->data.addr + (ULONG_PTR)wined3d_buffer_load_sysmem(vb, context)); } } } diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index d462ea5..9e36bcd 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -4081,7 +4081,7 @@ static void load_numbered_arrays(struct wined3d_context *context, * figure out the system memory address. */ const BYTE *ptr = element->data.addr; if (element->data.buffer_object) - ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, context); + ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(stream->buffer, context); if (context->numbered_array_mask & (1u << i)) unload_numbered_array(context, i); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 5e4b072..c3152a2 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3180,10 +3180,10 @@ static inline struct wined3d_buffer *buffer_from_resource(struct wined3d_resourc void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *context, struct wined3d_bo_address *data) DECLSPEC_HIDDEN; -BYTE *buffer_get_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) DECLSPEC_HIDDEN; void buffer_mark_used(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_state *state) DECLSPEC_HIDDEN; +BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) DECLSPEC_HIDDEN; HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_offset, struct wined3d_buffer *src_buffer, unsigned int src_offset, unsigned int size) DECLSPEC_HIDDEN; HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, -- 2.7.3 From jkucia at codeweavers.com Sun Oct 16 14:46:48 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Sun, 16 Oct 2016 21:46:48 +0200 Subject: [PATCH 5/6] wined3d: Explicitly track locations for buffers. In-Reply-To: <1476647209-11162-1-git-send-email-jkucia@codeweavers.com> References: <1476647209-11162-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476647209-11162-5-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- This is a first step to implement the location tracking for buffers and introduce invalidate/load/prepare location functions for buffers. Such API is required if we want to allow using double buffered buffers as stream output buffers or UAV buffers. The idea is to still track, internally, dirty areas of a buffer object. The buffers should work in the same way as before when there are no external calls to wined3d_buffer_invalidate(). Note: This patch depends on the fact that WINED3D_MAP_DISCARD and WINED3D_MAP_READONLY are never set simultaneously (see wined3d_resource_sanitise_map_flags()). --- dlls/wined3d/buffer.c | 79 ++++++++++++++++++++++++++++++++++++++---- dlls/wined3d/device.c | 1 + dlls/wined3d/wined3d_private.h | 3 ++ 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index b6338d1..c7f0d81 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -93,6 +93,46 @@ static BOOL buffer_is_fully_dirty(const struct wined3d_buffer *buffer) && !buffer->maps->offset && buffer->maps->size == buffer->resource.size; } +void wined3d_buffer_validate_location(struct wined3d_buffer *buffer, DWORD location) +{ + TRACE("buffer %p, location %s.\n", buffer, wined3d_debug_location(location)); + + if (location & WINED3D_LOCATION_BUFFER) + buffer_clear_dirty_areas(buffer); + + buffer->locations |= location; + + TRACE("New locations flags are %s.\n", wined3d_debug_location(buffer->locations)); +} + +static void wined3d_buffer_invalidate_range(struct wined3d_buffer *buffer, DWORD location, + unsigned int offset, unsigned int size) +{ + TRACE("buffer %p, location %s, offset %u, size %u.\n", + buffer, wined3d_debug_location(location), offset, size); + + if ((offset || size) && (location & ~WINED3D_LOCATION_BUFFER)) + { + ERR("Range can be invalidated only for WINED3D_LOCATION_BUFFER.\n"); + return; + } + + if (location & WINED3D_LOCATION_BUFFER) + buffer_invalidate_bo_range(buffer, offset, size); + + buffer->locations &= ~location; + + TRACE("New locations flags are %s.\n", wined3d_debug_location(buffer->locations)); + + if (!buffer->locations) + ERR("Buffer %p does not have any up to date location.\n", buffer); +} + +void wined3d_buffer_invalidate_location(struct wined3d_buffer *buffer, DWORD location) +{ + wined3d_buffer_invalidate_range(buffer, location, 0, 0); +} + /* Context activation is done by the caller. */ static void buffer_bind(struct wined3d_buffer *buffer, struct wined3d_context *context) { @@ -192,15 +232,21 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine This->buffer_object_usage = gl_usage; if (This->flags & WINED3D_BUFFER_DOUBLEBUFFER) + { buffer_invalidate_bo_range(This, 0, 0); + } else + { wined3d_resource_free_sysmem(&This->resource); + wined3d_buffer_validate_location(This, WINED3D_LOCATION_BUFFER); + wined3d_buffer_invalidate_location(This, WINED3D_LOCATION_SYSMEM); + } return; fail: /* Clean up all VBO init, but continue because we can work without a VBO :-) */ - ERR("Failed to create a vertex buffer object. Continuing, but performance issues may occur\n"); + ERR("Failed to create a vertex buffer object. Continuing, but performance issues may occur.\n"); This->flags &= ~WINED3D_BUFFER_USE_BO; delete_gl_buffer(This, gl_info); buffer_clear_dirty_areas(This); @@ -509,6 +555,8 @@ BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_c checkGLcall("buffer download"); buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER; + wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_SYSMEM); + return buffer->resource.heap_memory; } @@ -532,6 +580,7 @@ static void buffer_unload(struct wined3d_resource *resource) buffer->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER; } + wined3d_buffer_invalidate_location(buffer, WINED3D_LOCATION_BUFFER); delete_gl_buffer(buffer, context->gl_info); buffer_clear_dirty_areas(buffer); @@ -707,7 +756,7 @@ static void buffer_direct_upload(struct wined3d_buffer *This, struct wined3d_con } if (!map) { - ERR("Failed to map opengl buffer\n"); + ERR("Failed to map OpenGL buffer.\n"); return; } @@ -732,6 +781,8 @@ static void buffer_direct_upload(struct wined3d_buffer *This, struct wined3d_con } GL_EXTCALL(glUnmapBuffer(This->buffer_type_hint)); checkGLcall("glUnmapBuffer"); + + wined3d_buffer_validate_location(This, WINED3D_LOCATION_BUFFER); } void buffer_mark_used(struct wined3d_buffer *buffer) @@ -924,6 +975,8 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context * } HeapFree(GetProcessHeap(), 0, data); + + wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_BUFFER); } struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffer *buffer) @@ -952,17 +1005,28 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI if (buffer->buffer_object) { + unsigned int dirty_offset = offset, dirty_size = size; + /* DISCARD invalidates the entire buffer, regardless of the specified * offset and size. Some applications also depend on the entire buffer * being uploaded in that case. Two such applications are Port Royale * and Darkstar One. */ if (flags & WINED3D_MAP_DISCARD) - buffer_invalidate_bo_range(buffer, 0, 0); - else if (!(flags & WINED3D_MAP_READONLY)) - buffer_invalidate_bo_range(buffer, offset, size); + { + dirty_offset = 0; + dirty_size = 0; + } - if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) + if (buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER) { + if (!(flags & WINED3D_MAP_READONLY)) + wined3d_buffer_invalidate_range(buffer, WINED3D_LOCATION_BUFFER, dirty_offset, dirty_size); + } + else + { + if (!(flags & WINED3D_MAP_READONLY)) + buffer_invalidate_bo_range(buffer, dirty_offset, dirty_size); + if (count == 1) { struct wined3d_device *device = buffer->resource.device; @@ -1171,7 +1235,7 @@ HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_ } if (dst_buffer_mem) - buffer_invalidate_bo_range(dst_buffer, dst_offset, size); + wined3d_buffer_invalidate_range(dst_buffer, WINED3D_LOCATION_BUFFER, dst_offset, size); context_release(context); return WINED3D_OK; @@ -1300,6 +1364,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device return hr; } buffer->buffer_type_hint = bind_hint; + buffer->locations = WINED3D_LOCATION_SYSMEM; TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage, debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory, buffer); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 89b781c..a611531 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3179,6 +3179,7 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, { GL_EXTCALL(glDeleteBuffers(1, &buffer->buffer_object)); buffer->buffer_object = 0; + wined3d_buffer_invalidate_location(buffer, WINED3D_LOCATION_BUFFER); } if (e->data.addr) e->data.addr += e->stride * src_start_idx; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index c3152a2..45a24f1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3163,6 +3163,7 @@ struct wined3d_buffer struct wined3d_map_range *maps; ULONG maps_size, modified_areas; + DWORD locations; struct wined3d_event_query *query; /* conversion stuff */ @@ -3181,6 +3182,7 @@ static inline struct wined3d_buffer *buffer_from_resource(struct wined3d_resourc void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *context, struct wined3d_bo_address *data) DECLSPEC_HIDDEN; void buffer_mark_used(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; +void wined3d_buffer_invalidate_location(struct wined3d_buffer *buffer, DWORD location) DECLSPEC_HIDDEN; void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_state *state) DECLSPEC_HIDDEN; BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) DECLSPEC_HIDDEN; @@ -3188,6 +3190,7 @@ HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_ struct wined3d_buffer *src_buffer, unsigned int src_offset, unsigned int size) DECLSPEC_HIDDEN; HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, const struct wined3d_box *box, const void *data) DECLSPEC_HIDDEN; +void wined3d_buffer_validate_location(struct wined3d_buffer *buffer, DWORD location) DECLSPEC_HIDDEN; struct wined3d_rendertarget_view { -- 2.7.3 From jkucia at codeweavers.com Sun Oct 16 14:46:49 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Sun, 16 Oct 2016 21:46:49 +0200 Subject: [PATCH 6/6] wined3d: Rename buffer_invalidate_bo_range() to buffer_mark_dirty_area(). In-Reply-To: <1476647209-11162-1-git-send-email-jkucia@codeweavers.com> References: <1476647209-11162-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476647209-11162-6-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index c7f0d81..a0a4194 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -41,7 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); #define VB_MAXFULLCONVERSIONS 5 /* Number of full conversions before we stop converting */ #define VB_RESETFULLCONVS 20 /* Reset full conversion counts after that number of draws */ -static void buffer_invalidate_bo_range(struct wined3d_buffer *buffer, unsigned int offset, unsigned int size) +static void buffer_mark_dirty_area(struct wined3d_buffer *buffer, unsigned int offset, unsigned int size) { if (!offset && (!size || size == buffer->resource.size)) goto invalidate_all; @@ -118,7 +118,7 @@ static void wined3d_buffer_invalidate_range(struct wined3d_buffer *buffer, DWORD } if (location & WINED3D_LOCATION_BUFFER) - buffer_invalidate_bo_range(buffer, offset, size); + buffer_mark_dirty_area(buffer, offset, size); buffer->locations &= ~location; @@ -233,7 +233,7 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine if (This->flags & WINED3D_BUFFER_DOUBLEBUFFER) { - buffer_invalidate_bo_range(This, 0, 0); + buffer_mark_dirty_area(This, 0, 0); } else { @@ -871,7 +871,7 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context * /* The declaration changed, reload the whole buffer. */ WARN("Reloading buffer because of a vertex declaration change.\n"); - buffer_invalidate_bo_range(buffer, 0, 0); + buffer_mark_dirty_area(buffer, 0, 0); /* Avoid unfenced updates, we might overwrite more areas of the buffer than the application * cleared for unsynchronized updates @@ -1025,7 +1025,7 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI else { if (!(flags & WINED3D_MAP_READONLY)) - buffer_invalidate_bo_range(buffer, dirty_offset, dirty_size); + buffer_mark_dirty_area(buffer, dirty_offset, dirty_size); if (count == 1) { -- 2.7.3 From aric at codeweavers.com Sun Oct 16 23:41:35 2016 From: aric at codeweavers.com (Aric Stewart) Date: Mon, 17 Oct 2016 06:41:35 +0200 Subject: [PATCH] winebus.sys: Handle device reports for hidraw devices Message-ID: Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 3 ++ dlls/winebus.sys/bus_udev.c | 63 +++++++++++++++++++++++++++++ dlls/winebus.sys/main.c | 97 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 162 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-winebus.sys-Handle-device-reports-for-hidraw-devices.txt Type: text/x-patch Size: 9541 bytes Desc: not available URL: From aric at codeweavers.com Mon Oct 17 08:29:06 2016 From: aric at codeweavers.com (Aric Stewart) Date: Mon, 17 Oct 2016 15:29:06 +0200 Subject: [PATCH v2] winebus.sys: Handle device reports for hidraw devices Message-ID: <2fc6c521-0bc7-46ae-bbf3-32546284550e@codeweavers.com> v2: Suggestions from Sebastian Lackner Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 3 ++ dlls/winebus.sys/bus_udev.c | 73 ++++++++++++++++++++++++++ dlls/winebus.sys/main.c | 123 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 198 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: v2-0001-winebus.sys-Handle-device-reports-for-hidraw-device.txt Type: text/x-patch Size: 10938 bytes Desc: not available URL: From aric at codeweavers.com Mon Oct 17 08:58:24 2016 From: aric at codeweavers.com (Aric Stewart) Date: Mon, 17 Oct 2016 15:58:24 +0200 Subject: [PATCH v2 1/2] include: Correct NTSTATUS declaration for hidsdi.h Message-ID: <0a8b91dc-fe4c-ae15-d5fa-17283e005a27@codeweavers.com> Signed-off-by: Aric Stewart --- include/ddk/hidsdi.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: v2-0001-include-Correct-NTSTATUS-declaration-for-hidsdi.h.txt Type: text/x-patch Size: 481 bytes Desc: not available URL: From aric at codeweavers.com Mon Oct 17 08:58:32 2016 From: aric at codeweavers.com (Aric Stewart) Date: Mon, 17 Oct 2016 15:58:32 +0200 Subject: [PATCH v2 2/2] hid/tests: Add HID device enumeration test Message-ID: <59ef7fe0-0744-43c5-2397-906ffe05ea3c@codeweavers.com> v2: Suggestions from Sebastian Lackner Signed-off-by: Aric Stewart --- configure | 1 + configure.ac | 1 + dlls/hid/tests/Makefile.in | 5 +++ dlls/hid/tests/device.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+) create mode 100644 dlls/hid/tests/Makefile.in create mode 100644 dlls/hid/tests/device.c -------------- next part -------------- A non-text attachment was scrubbed... Name: v2-0002-hid-tests-Add-HID-device-enumeration-test.txt Type: text/x-patch Size: 4572 bytes Desc: not available URL: From aric at codeweavers.com Mon Oct 17 10:14:37 2016 From: aric at codeweavers.com (Aric Stewart) Date: Mon, 17 Oct 2016 17:14:37 +0200 Subject: [PATCH v3] winebus.sys: Handle device reports for hidraw devices Message-ID: <22d2bfcd-ec06-93dc-5412-3057fe88a20e@codeweavers.com> v2: Suggestions from Sebastian Lackner v3: Further suggestions from Sebastian Lackner Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 3 + dlls/winebus.sys/bus_udev.c | 73 ++++++++++++++++++++++++ dlls/winebus.sys/main.c | 133 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 208 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: v3-0003-winebus.sys-Handle-device-reports-for-hidraw-device.txt Type: text/x-patch Size: 11058 bytes Desc: not available URL: From lauri.kentta at gmail.com Mon Oct 17 12:01:57 2016 From: lauri.kentta at gmail.com (=?UTF-8?q?Lauri=20Kentt=C3=A4?=) Date: Mon, 17 Oct 2016 20:01:57 +0300 Subject: [PATCH] po: Update Finnish translation. Message-ID: <20161017170157.5389-1-lauri.kentta@gmail.com> Signed-off-by: Lauri Kenttä --- po/fi.po | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/po/fi.po b/po/fi.po index 7621cd7..c03f0a8 100644 --- a/po/fi.po +++ b/po/fi.po @@ -10487,10 +10487,8 @@ msgid "IPv6 address" msgstr "IPv6-osoite" #: msinfo32.rc:28 -#, fuzzy -#| msgid "System Configuration" msgid "System Information" -msgstr "Järjestelmän kokoonpano" +msgstr "Järjestelmätiedot" #: net.rc:30 msgid "" @@ -14471,10 +14469,8 @@ msgid "Error: Invalid query\n" msgstr "Virhe: Virheellinen kysely\n" #: wmic.rc:31 -#, fuzzy -#| msgid "reg: Invalid syntax. " msgid "Error: Invalid syntax for PATH\n" -msgstr "reg: Syntaksi ei kelpaa. " +msgstr "Virhe: Virheellinen syntaksi komennolle PATH\n" #: wordpad.rc:31 msgid "&New...\tCtrl+N" @@ -14549,36 +14545,32 @@ msgid "F&ormat" msgstr "&Muotoile" #: wordpad.rc:85 -#, fuzzy -#| msgid "&List" msgid "&Lists" -msgstr "&Lista" +msgstr "&Listat" #: wordpad.rc:87 wordpad.rc:116 msgid "&Bullet points" msgstr "&Listan kohdat" #: wordpad.rc:88 -#, fuzzy -#| msgid "CRL Number" msgid "Numbers" -msgstr "Sulkulistan numero" +msgstr "Luvut" #: wordpad.rc:89 msgid "Letters - lower case" -msgstr "" +msgstr "Kirjaimet - pienaakkoset" #: wordpad.rc:90 msgid "Letters - upper case" -msgstr "" +msgstr "Kirjaimet - suuraakkoset" #: wordpad.rc:91 msgid "Roman numerals - lower case" -msgstr "" +msgstr "Roomalaiset numerot - pienaakkoset" #: wordpad.rc:92 msgid "Roman numerals - upper case" -msgstr "" +msgstr "Roomalaiset numerot - suuraakkoset" #: wordpad.rc:94 wordpad.rc:117 msgid "&Paragraph..." -- 2.10.0 From jacek at codeweavers.com Mon Oct 17 12:32:07 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 17 Oct 2016 19:32:07 +0200 Subject: wintrust: Don't close key if RegOpenKeyExW failed. Message-ID: <7dcf7dc2-7752-9a5a-c71f-47921e31008c@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/wintrust/register.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-wintrust-Don-t-close-key-if-RegOpenKeyExW-failed.diff Type: text/x-patch Size: 530 bytes Desc: not available URL: From rpisl at seznam.cz Mon Oct 17 13:21:49 2016 From: rpisl at seznam.cz (=?UTF-8?q?Roman=20Pi=C5=A1l?=) Date: Mon, 17 Oct 2016 20:21:49 +0200 Subject: [PATCH] ws2_32: Allow user to enable IP dual stack (v4). Message-ID: <1476728509-2511-1-git-send-email-rpisl@seznam.cz> IP dual stack (v4+v6) should be disabled by default, but previous code was setting IPV6_V6ONLY in bind() which prevented user to override it. This patch moves setting IPV6_V6ONLY to socket creation time. Based on https://www.winehq.org/pipermail/wine-patches/2016-July/151919.html Signed-off-by: Matthieu Nottale Signed-off-by: Roman Pišl --- dlls/ws2_32/socket.c | 23 +++++++++------------- dlls/ws2_32/tests/sock.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index e8c5130..d14e9d6 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3240,20 +3240,6 @@ int WINAPI WS_bind(SOCKET s, const struct WS_sockaddr* name, int namelen) } else { -#ifdef IPV6_V6ONLY - const struct sockaddr_in6 *in6 = (const struct sockaddr_in6*) &uaddr; - if (name->sa_family == WS_AF_INET6 && - !memcmp(&in6->sin6_addr, &in6addr_any, sizeof(struct in6_addr))) - { - int enable = 1; - if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable)) == -1) - { - release_sock_fd( s, fd ); - SetLastError(WSAEAFNOSUPPORT); - return SOCKET_ERROR; - } - } -#endif if (name->sa_family == WS_AF_INET) { struct sockaddr_in *in4 = (struct sockaddr_in*) &uaddr; @@ -7233,6 +7219,15 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, TRACE("\tcreated %04lx\n", ret ); if (ipxptype > 0) set_ipx_packettype(ret, ipxptype); + +#ifdef IPV6_V6ONLY + if (unixaf == AF_INET6) + { + int enable = 1; + int fd = get_sock_fd(ret, 0, NULL); + setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable)); + } +#endif return ret; } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index a144bd3..a676255 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1732,7 +1732,7 @@ static void test_so_reuseaddr(void) DWORD err; saddr.sin_family = AF_INET; - saddr.sin_port = htons(9375); + saddr.sin_port = htons(SERVERPORT+1); saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); s1=socket(AF_INET, SOCK_STREAM, 0); @@ -6110,6 +6110,8 @@ static void test_ipv6only(void) struct sockaddr_in sin4; struct sockaddr_in6 sin6; int ret; + int enabled; + int len; memset(&sin4, 0, sizeof(sin4)); sin4.sin_family = AF_INET; @@ -6142,6 +6144,50 @@ static void test_ipv6only(void) ok(!ret, "Could not bind IPv4 address (LastError: %d; %d expected if IPv6 binds to IPv4 as well).\n", WSAGetLastError(), WSAEADDRINUSE); + closesocket(v4); + closesocket(v6); + v4 = INVALID_SOCKET; + v6 = INVALID_SOCKET; + + /* Test again, this time disabling V6ONLY. */ + sin4.sin_port = htons(SERVERPORT+2); + sin6.sin6_port = htons(SERVERPORT+2); + + v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + ok(v6 != INVALID_SOCKET, "Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n", + WSAGetLastError(), WSAEAFNOSUPPORT); + + enabled = 2; + len = sizeof(enabled); + ret = getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len); + if (ret) { + skip("Could not check IPV6_V6ONLY (option not supported?) ((LastError: %d).\n", WSAGetLastError()); + goto end; + } + ok(enabled == 1, "IPV6_V6ONLY is not enabled by default.\n"); + + enabled = 0; + ret = setsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len); + ok(!ret, "Failed to disable IPV6_V6ONLY (LastError: %d).\n", WSAGetLastError()); + + ret = bind(v6, (struct sockaddr*)&sin6, sizeof(sin6)); + ok(!ret, "Could not bind IPv6 address (LastError: %d).\n", WSAGetLastError()); + + enabled = 2; + len = sizeof(enabled); + getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len); + ok(enabled == 0, "IPV6_V6ONLY is enabled after bind.\n"); + + v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + ok(v4 != INVALID_SOCKET, "Could not create IPv4 socket (LastError: %d).\n", + WSAGetLastError()); + + WSASetLastError(0xdeadbeef); + bind(v4, (struct sockaddr*)&sin4, sizeof(sin4)); + + ok(WSAGetLastError() == WSAEADDRINUSE, "Failed to disable IPV6_V6ONLY (LastError: %d; %d expected if IPv6 binds to IPv4 as well).\n", + WSAGetLastError(), WSAEADDRINUSE); + end: if (v4 != INVALID_SOCKET) closesocket(v4); @@ -8024,7 +8070,7 @@ static void test_TransmitFile(void) /* Setup a properly connected socket for transfers */ memset(&bindAddress, 0, sizeof(bindAddress)); bindAddress.sin_family = AF_INET; - bindAddress.sin_port = htons(9375); + bindAddress.sin_port = htons(SERVERPORT+1); bindAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); iret = bind(server, (struct sockaddr*)&bindAddress, sizeof(bindAddress)); if (iret != 0) -- 2.7.3 From jacek at codeweavers.com Mon Oct 17 14:22:16 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 17 Oct 2016 21:22:16 +0200 Subject: [PATCH 1/4] ntdll/tests: Added more registry symlink tests. Message-ID: Signed-off-by: Jacek Caban --- dlls/ntdll/reg.c | 2 +- dlls/ntdll/tests/reg.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-ntdll-tests-Added-more-registry-symlink-tests.diff Type: text/x-patch Size: 4143 bytes Desc: not available URL: From jacek at codeweavers.com Mon Oct 17 14:22:28 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 17 Oct 2016 21:22:28 +0200 Subject: [PATCH 2/4] ntdll: Return NULL key on NtCreateKey failure. Message-ID: <11b1952e-dbdb-2187-78eb-f86d5837e8bb@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/ntdll/reg.c | 8 +++----- dlls/ntdll/tests/reg.c | 12 +++++++++++- server/registry.c | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-ntdll-Return-NULL-key-on-NtCreateKey-failure.diff Type: text/x-patch Size: 3489 bytes Desc: not available URL: From jacek at codeweavers.com Mon Oct 17 14:22:36 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 17 Oct 2016 21:22:36 +0200 Subject: [PATCH 3/4] advapi32: Pass options argument to NtOpenFileEx. Message-ID: <37c74723-bd5a-3269-7dda-022893680540@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/advapi32/registry.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0003-advapi32-Pass-open-argument-to-NtOpenFileEx.diff Type: text/x-patch Size: 3744 bytes Desc: not available URL: From jacek at codeweavers.com Mon Oct 17 14:22:45 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 17 Oct 2016 21:22:45 +0200 Subject: [PATCH 4/4] advapi32: Initialize retkey value in open_key. Message-ID: Office 2013 registry virtualization depends on this. Its NtOpenKey[Ex] hook doesn't set it to NULL, but it's expected to be NULL. Signed-off-by: Jacek Caban --- dlls/advapi32/registry.c | 2 ++ 1 file changed, 2 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0004-advapi32-Initialize-retkey-value-in-open_key.diff Type: text/x-patch Size: 493 bytes Desc: not available URL: From rpisl at seznam.cz Mon Oct 17 17:34:55 2016 From: rpisl at seznam.cz (=?UTF-8?q?Roman=20Pi=C5=A1l?=) Date: Tue, 18 Oct 2016 00:34:55 +0200 Subject: [PATCH] user32: Fix buffer overflow in EDIT_EM_ReplaceSel(). Message-ID: <1476743695-13829-1-git-send-email-rpisl@seznam.cz> After EN_MAXTEXT notification, available space may be larger than length of the string. This must be checked and strl must not be set to a value larger than the actual length of the string. Fixes bug https://bugs.winehq.org/show_bug.cgi?id=23838 (tested) and probably https://bugs.winehq.org/show_bug.cgi?id=13319. Signed-off-by: Roman Pišl --- dlls/user32/edit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c index f5cd3c4..78d78ea 100644 --- a/dlls/user32/edit.c +++ b/dlls/user32/edit.c @@ -2598,7 +2598,7 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, LPCWSTR lpsz_replac if (es->buffer_limit < (tl - (e-s))) strl = 0; else - strl = es->buffer_limit - (tl - (e-s)); + strl = min(strl, es->buffer_limit - (tl - (e-s))); } if (!EDIT_MakeFit(es, tl - (e - s) + strl)) -- 2.7.4 From leslie_alistair at hotmail.com Tue Oct 18 02:13:34 2016 From: leslie_alistair at hotmail.com (Alistair Leslie-Hughes) Date: Tue, 18 Oct 2016 07:13:34 +0000 Subject: [PATCH] comtrl32/treeview: Display state value as hex. Message-ID: --- dlls/comctl32/treeview.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c index 117b309..70d6362 100644 --- a/dlls/comctl32/treeview.c +++ b/dlls/comctl32/treeview.c @@ -4448,7 +4448,7 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect, assert(newSelect == NULL || TREEVIEW_ValidItem(infoPtr, newSelect)); - TRACE("Entering item %p (%s), flag 0x%x, cause 0x%x, state %d\n", + TRACE("Entering item %p (%s), flag 0x%x, cause 0x%x, state 0x%x\n", newSelect, TREEVIEW_ItemName(newSelect), action, cause, newSelect ? newSelect->state : 0); @@ -4523,7 +4523,7 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect, break; } - TRACE("Leaving state %d\n", newSelect ? newSelect->state : 0); + TRACE("Leaving state 0x%x\n", newSelect ? newSelect->state : 0); return TRUE; } -- 1.9.1 From leslie_alistair at hotmail.com Tue Oct 18 02:13:47 2016 From: leslie_alistair at hotmail.com (Alistair Leslie-Hughes) Date: Tue, 18 Oct 2016 07:13:47 +0000 Subject: [PATCH 1/2] dpnet: Implement IDirectPlay8LobbyClient Initialize In-Reply-To: <20161018071314.9437-1-leslie_alistair@hotmail.com> References: <20161018071314.9437-1-leslie_alistair@hotmail.com> Message-ID: Signed-off-by: Alistair Leslie-Hughes --- dlls/dpnet/client.c | 15 +++++++++++++-- dlls/dpnet/tests/client.c | 5 ++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/dlls/dpnet/client.c b/dlls/dpnet/client.c index f865aa7..f6ab0f7 100644 --- a/dlls/dpnet/client.c +++ b/dlls/dpnet/client.c @@ -45,6 +45,10 @@ typedef struct IDirectPlay8LobbyClientImpl { IDirectPlay8LobbyClient IDirectPlay8LobbyClient_iface; LONG ref; + + PFNDPNMESSAGEHANDLER msghandler; + DWORD flags; + void *usercontext; } IDirectPlay8LobbyClientImpl; static inline IDirectPlay8LobbyClientImpl *impl_from_IDirectPlay8LobbyClient(IDirectPlay8LobbyClient *iface) @@ -1093,9 +1097,16 @@ static HRESULT WINAPI lobbyclient_Initialize(IDirectPlay8LobbyClient *iface, voi { IDirectPlay8LobbyClientImpl *This = impl_from_IDirectPlay8LobbyClient(iface); - FIXME("(%p)->(%p %p 0x%08x)\n", This, context, msghandler, flags); + TRACE("(%p):(%p,%p,%x)\n", This, context, msghandler, flags); - return E_NOTIMPL; + if(!msghandler) + return E_POINTER; + + This->usercontext = context; + This->msghandler = msghandler; + This->flags = flags; + + return DPN_OK; } static HRESULT WINAPI lobbyclient_EnumLocalPrograms(IDirectPlay8LobbyClient *iface, GUID* guidapplication, diff --git a/dlls/dpnet/tests/client.c b/dlls/dpnet/tests/client.c index 723f7be..753d3ad 100644 --- a/dlls/dpnet/tests/client.c +++ b/dlls/dpnet/tests/client.c @@ -221,8 +221,11 @@ static void test_lobbyclient(void) ok(hr == S_OK, "Failed to create object\n"); if(SUCCEEDED(hr)) { + hr = IDirectPlay8LobbyClient_Initialize(client, NULL, NULL, 0); + ok(hr == E_POINTER, "got 0x%08x\n", hr); + hr = IDirectPlay8LobbyClient_Initialize(client, NULL, DirectPlayLobbyClientMessageHandler, 0); - todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08x\n", hr); hr = IDirectPlay8LobbyClient_Close(client, 0); todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); -- 1.9.1 From leslie_alistair at hotmail.com Tue Oct 18 02:13:59 2016 From: leslie_alistair at hotmail.com (Alistair Leslie-Hughes) Date: Tue, 18 Oct 2016 07:13:59 +0000 Subject: [PATCH 2/2] dpnet: Report no programs found in IDirectPlay8LobbyClient EnumLocalPrograms In-Reply-To: <20161018071314.9437-1-leslie_alistair@hotmail.com> References: <20161018071314.9437-1-leslie_alistair@hotmail.com> Message-ID: Signed-off-by: Alistair Leslie-Hughes --- dlls/dpnet/client.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dlls/dpnet/client.c b/dlls/dpnet/client.c index f6ab0f7..ee7b76a 100644 --- a/dlls/dpnet/client.c +++ b/dlls/dpnet/client.c @@ -1116,7 +1116,10 @@ static HRESULT WINAPI lobbyclient_EnumLocalPrograms(IDirectPlay8LobbyClient *ifa FIXME("(%p)->(%p %p %p %p 0x%08x)\n", This, guidapplication, enumdata, enumDataSize, items, flags); - return E_NOTIMPL; + if(enumDataSize) + *enumDataSize = 0; + + return S_OK; } static HRESULT WINAPI lobbyclient_ConnectApplication(IDirectPlay8LobbyClient *iface, DPL_CONNECT_INFO *connectioninfo, -- 1.9.1 From aric at codeweavers.com Tue Oct 18 02:35:22 2016 From: aric at codeweavers.com (Aric Stewart) Date: Tue, 18 Oct 2016 09:35:22 +0200 Subject: [5/5] hidclass.sys: Use MmGetSystemAddressForMdlSafe to access MDL data. Message-ID: <2b89069a-df3f-5083-0355-514bc3933162@codeweavers.com> Signed-off-by: Aric Stewart From rpisl at seznam.cz Tue Oct 18 03:46:54 2016 From: rpisl at seznam.cz (=?UTF-8?q?Roman=20Pi=C5=A1l?=) Date: Tue, 18 Oct 2016 10:46:54 +0200 Subject: [PATCH] ws2_32: Allow user to enable IP dual stack (v5). Message-ID: <1476780414-25531-1-git-send-email-rpisl@seznam.cz> IP dual stack (v4+v6) should be disabled by default, but previous code was setting IPV6_V6ONLY in bind() which prevented user to override it. This patch moves setting IPV6_V6ONLY to socket creation time. V5 - fixes failing test on Windows Based on https://www.winehq.org/pipermail/wine-patches/2016-July/151919.html Signed-off-by: Matthieu Nottale Signed-off-by: Roman Pišl --- dlls/ws2_32/socket.c | 23 +++++++----------- dlls/ws2_32/tests/sock.c | 62 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 67 insertions(+), 18 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index e8c5130..d14e9d6 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3240,20 +3240,6 @@ int WINAPI WS_bind(SOCKET s, const struct WS_sockaddr* name, int namelen) } else { -#ifdef IPV6_V6ONLY - const struct sockaddr_in6 *in6 = (const struct sockaddr_in6*) &uaddr; - if (name->sa_family == WS_AF_INET6 && - !memcmp(&in6->sin6_addr, &in6addr_any, sizeof(struct in6_addr))) - { - int enable = 1; - if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable)) == -1) - { - release_sock_fd( s, fd ); - SetLastError(WSAEAFNOSUPPORT); - return SOCKET_ERROR; - } - } -#endif if (name->sa_family == WS_AF_INET) { struct sockaddr_in *in4 = (struct sockaddr_in*) &uaddr; @@ -7233,6 +7219,15 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, TRACE("\tcreated %04lx\n", ret ); if (ipxptype > 0) set_ipx_packettype(ret, ipxptype); + +#ifdef IPV6_V6ONLY + if (unixaf == AF_INET6) + { + int enable = 1; + int fd = get_sock_fd(ret, 0, NULL); + setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable)); + } +#endif return ret; } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index a144bd3..19b1985 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1732,7 +1732,7 @@ static void test_so_reuseaddr(void) DWORD err; saddr.sin_family = AF_INET; - saddr.sin_port = htons(9375); + saddr.sin_port = htons(SERVERPORT+1); saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); s1=socket(AF_INET, SOCK_STREAM, 0); @@ -6110,6 +6110,8 @@ static void test_ipv6only(void) struct sockaddr_in sin4; struct sockaddr_in6 sin6; int ret; + int enabled; + int len; memset(&sin4, 0, sizeof(sin4)); sin4.sin_family = AF_INET; @@ -6139,8 +6141,60 @@ static void test_ipv6only(void) goto end; } ret = bind(v4, (struct sockaddr*)&sin4, sizeof(sin4)); - ok(!ret, "Could not bind IPv4 address (LastError: %d; %d expected if IPv6 binds to IPv4 as well).\n", - WSAGetLastError(), WSAEADDRINUSE); + ok(!ret, "Could not bind IPv4 address (LastError: %d).\n", + WSAGetLastError()); + + closesocket(v4); + closesocket(v6); + v4 = INVALID_SOCKET; + v6 = INVALID_SOCKET; + + /* Test again, this time disabling V6ONLY. */ + sin4.sin_port = htons(SERVERPORT+2); + sin6.sin6_port = htons(SERVERPORT+2); + + v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + ok(v6 != INVALID_SOCKET, "Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n", + WSAGetLastError(), WSAEAFNOSUPPORT); + + enabled = 2; + len = sizeof(enabled); + ret = getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len); + if (ret) { + skip("Could not check IPV6_V6ONLY (option not supported?) ((LastError: %d).\n", WSAGetLastError()); + goto end; + } + ok(enabled == 1, "IPV6_V6ONLY is not enabled by default.\n"); + + enabled = 0; + ret = setsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len); + ok(!ret, "Failed to disable IPV6_V6ONLY (LastError: %d).\n", WSAGetLastError()); + + enabled = 1; + ret = setsockopt(v6, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&enabled, len); + ok(!ret, "Failed to set SO_EXCLUSIVEADDRUSE on IPv6 socket (LastError: %d).\n", WSAGetLastError()); + + ret = bind(v6, (struct sockaddr*)&sin6, sizeof(sin6)); + ok(!ret, "Could not bind IPv6 address (LastError: %d).\n", WSAGetLastError()); + + enabled = 2; + len = sizeof(enabled); + getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len); + ok(enabled == 0, "IPV6_V6ONLY is enabled after bind.\n"); + + v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + ok(v4 != INVALID_SOCKET, "Could not create IPv4 socket (LastError: %d).\n", + WSAGetLastError()); + + enabled = 1; + ret = setsockopt(v4, SOL_SOCKET, SO_REUSEADDR, (char*)&enabled, len); + ok(!ret, "Failed to set SO_REUSEADDR on IPv4 socket (LastError: %d).\n", WSAGetLastError()); + + WSASetLastError(0xdeadbeef); + bind(v4, (struct sockaddr*)&sin4, sizeof(sin4)); + + ok(WSAGetLastError() == WSAEACCES, "Failed to disable IPV6_V6ONLY (LastError: %d; %d expected if IPv6 binds to IPv4 as well).\n", + WSAGetLastError(), WSAEACCES); end: if (v4 != INVALID_SOCKET) @@ -8024,7 +8078,7 @@ static void test_TransmitFile(void) /* Setup a properly connected socket for transfers */ memset(&bindAddress, 0, sizeof(bindAddress)); bindAddress.sin_family = AF_INET; - bindAddress.sin_port = htons(9375); + bindAddress.sin_port = htons(SERVERPORT+1); bindAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); iret = bind(server, (struct sockaddr*)&bindAddress, sizeof(bindAddress)); if (iret != 0) -- 2.7.3 From jacek at codeweavers.com Tue Oct 18 07:28:59 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Tue, 18 Oct 2016 14:28:59 +0200 Subject: ws2_32: Added FreeAddrInfoExW stub. Message-ID: <895967ba-d23f-280a-783c-9995e4614413@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/ws2_32/socket.c | 8 ++++++++ dlls/ws2_32/ws2_32.spec | 1 + 2 files changed, 9 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-ws2_32-Added-FreeAddrInfoExW-stub.diff Type: text/x-patch Size: 946 bytes Desc: not available URL: From donat at enikeev.net Tue Oct 18 07:59:15 2016 From: donat at enikeev.net (Donat Enikeev) Date: Tue, 18 Oct 2016 15:59:15 +0300 Subject: [PATCH 1/2] crypt32/tests: whether apps could write to the registry HKLM Root certificates store Message-ID: <1476795555-5813-1-git-send-email-donat@enikeev.net> And, additionally, whether CertAddStoreToCollection() respects read-only flag and priorities Signed-off-by: Donat Enikeev --- dlls/crypt32/tests/store.c | 217 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c index 4483936..c9989ff 100644 --- a/dlls/crypt32/tests/store.c +++ b/dlls/crypt32/tests/store.c @@ -345,6 +345,220 @@ static const BYTE serializedStoreWithCert[] = { 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00 }; +/* Testing whether HKLM\Root store in the collection is availble for adding new certs*/ +static void testRootStoresInCollection(void) +{ + PCCERT_CONTEXT cert1, cert2; + HCERTSTORE collection; + WCHAR keyName[MAX_PATH]; + static const WCHAR rootW[] = {'R','o','o','t',0}, + certificatesW[] = {'C','e','r','t','i','f','i','c','a','t','e','s',0 }, + slashW[] = { '\\',0 }, + bigCert_hashStrW[] = { + '6','E','3','0','9','0','7','1','5','F','D','9','2','3', + '5','6','E','B','A','E','2','5','4','0','E','6','2','2', + 'D','A','1','9','2','6','0','2','A','6','0','8',0}; + HKEY key; + BOOL ret; + DWORD res; + + /* Special case of HKLM Root store, with system certificates merged via collection*/ + collection = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_SYSTEM_STORE_LOCAL_MACHINE, rootW); + if (!collection) + { + win_skip("Insufficient privileges for the test, skipping\n"); + return; + } + ok (collection!=NULL, "Failed to open root store %x", GetLastError()); + cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); + ok (cert1 != NULL, "Create cert context failed %x\n", GetLastError()); + ret = CertAddCertificateContextToStore(collection, cert1, CERT_STORE_ADD_REPLACE_EXISTING, NULL); + ok (ret, "Adding to root collection failed %x\n", GetLastError()); + CertFreeCertificateContext(cert1); + CertCloseStore(collection, 0); + + lstrcpyW(keyName, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH); + lstrcatW(keyName, slashW); + lstrcatW(keyName, rootW); + lstrcatW(keyName, slashW); + lstrcatW(keyName, certificatesW); + lstrcatW(keyName, slashW); + lstrcatW(keyName, bigCert_hashStrW); + + res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName, 0, KEY_ALL_ACCESS, &key); + ok (!res, "The cert hasn't been saved %x\n", GetLastError()); + if (!res) RegCloseKey(key); + + /* deleting cert from store */ + collection = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_SYSTEM_STORE_LOCAL_MACHINE, rootW); + ok (collection!=NULL, "Failed to open root store %x", GetLastError()); + cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); + ok (cert1 != NULL, "Create cert context failed %x\n", GetLastError()); + cert2 = CertFindCertificateInStore(collection, X509_ASN_ENCODING, 0, CERT_FIND_EXISTING, cert1, NULL); + ok (cert2 != NULL, "Failed to find cert in the store %x\n", GetLastError()); + ret = CertDeleteCertificateFromStore(cert2); + ok (ret, "Failed to delete certificate from store %x\n", GetLastError()); + CertFreeCertificateContext(cert1); + CertFreeCertificateContext(cert2); + CertCloseStore(collection, 0); + + res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName, 0, KEY_ALL_ACCESS, &key); + ok (res, "The cert's registry entry should be absent %x\n", GetLastError()); + if (res) RegCloseKey(key); +} + +/** + * @see testCollectionStore() additionally + * this test checks that certificate falls into correct store of a collection + * depending on the access flags and priorities + */ +static void testStoresInCollection(void) +{ + PCCERT_CONTEXT cert1, cert2, tcert1; + HCERTSTORE collection, ro_store, rw_store, rw_store_2, tstore; + static const WCHAR WineTestRO_W[] = { 'W','i','n','e','T','e','s','t','_','R','O',0 }, + WineTestRW_W[] = { 'W','i','n','e','T','e','s','t','_','R','W',0 }, + WineTestRW2_W[]= { 'W','i','n','e','T','e','s','t','_','R','W','2',0 }; + BOOL ret; + + if (!pCertAddStoreToCollection) + { + win_skip("CertAddStoreToCollection() is not available\n"); + return; + } + if (0) { + collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + ok(collection != NULL, "Failed to init collection store, last error %x\n", GetLastError()); + /* Add read-only store to collection with very high priority*/ + ro_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, + CERT_SYSTEM_STORE_CURRENT_USER, WineTestRO_W); + ok(ro_store != NULL, "Failed to init ro store %x\n", GetLastError()); + + ret = CertAddStoreToCollection(collection, ro_store, 0, 1000); + ok (ret, "Failed to add read-only store to collection %x\n", GetLastError()); + + cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); + ok (cert1 != NULL, "Create cert context failed %x\n", GetLastError()); + ret = CertAddCertificateContextToStore(collection, cert1, CERT_STORE_ADD_ALWAYS, NULL); + ok (!ret, "Added cert to collection with single read-only store %x\n", GetLastError()); + + /* Add read-write store to collection with the lowest priority*/ + rw_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, + CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW_W); + ok (rw_store != NULL, "Failed to open rw store %x\n", GetLastError()); + ret = CertAddStoreToCollection(collection, rw_store, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); + ok (ret, "Failed to add rw store to collection %x\n", GetLastError()); + /** Adding certificate to collection should fall into rw store, + * even though prioirty of the ro_store is higher */ + ret = CertAddCertificateContextToStore(collection, cert1, CERT_STORE_ADD_REPLACE_EXISTING, NULL); + ok (ret, "Failed to add cert to the collection %x\n", GetLastError()); + + tcert1 = CertEnumCertificatesInStore(ro_store, NULL); + ok (!tcert1, "Read-only ro_store contains cert\n"); + + tcert1 = CertEnumCertificatesInStore(rw_store, NULL); + ok (cert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, + "Unexpected cert in the rw store\n"); + CertFreeCertificateContext(tcert1); + + tcert1 = CertEnumCertificatesInStore(collection, NULL); + ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, + "Unexpected cert in the collection\n"); + CertFreeCertificateContext(tcert1); + + /** adding one more rw store with higher priority*/ + rw_store_2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, + CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW2_W); + ok (rw_store_2 != NULL, "Failed to init second rw store %x\n", GetLastError()); + ret = CertAddStoreToCollection(collection, rw_store_2, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 50); + ok (ret, "Failed to add rw_store_2 to collection %x\n",GetLastError()); + + cert2 = CertCreateCertificateContext(X509_ASN_ENCODING, signedBigCert, sizeof(signedBigCert)); + ok (cert2 != NULL, "Failed to create cert context %x \n", GetLastError()); + ret = CertAddCertificateContextToStore(collection, cert2, CERT_STORE_ADD_REPLACE_EXISTING, NULL); + ok (ret, "Failed to add cert3 to the store %x\n",GetLastError()); + + /** checking certificates in the stores */ + tcert1 = CertEnumCertificatesInStore(ro_store, 0); + ok (tcert1 == NULL, "Read-only store not empty\n"); + + tcert1 = CertEnumCertificatesInStore(rw_store, NULL); + ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, + "Unexpected cert in the rw_store\n"); + CertFreeCertificateContext(tcert1); + + tcert1 = CertEnumCertificatesInStore(rw_store_2, NULL); + ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded, + "Unexpected cert in the rw_store_2\n"); + CertFreeCertificateContext(tcert1); + + /** checking certificates in the collection */ + tcert1 = CertEnumCertificatesInStore(collection, NULL); + ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded, + "cert2 expected in the collection got %p, %x\n",tcert1, GetLastError()); + tcert1 = CertEnumCertificatesInStore(collection, tcert1); + ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, + "cert1 expected in the collection got %p, %x\n",tcert1, GetLastError()); + tcert1 = CertEnumCertificatesInStore(collection, tcert1); + ok (tcert1==NULL,"Unexpected cert in the collection %p %x\n",tcert1, GetLastError()); + + /* checking whether certs had been saved (they are NOT in wine until stores are closed*/ + tstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, WineTestRW_W); + ok (tstore!=NULL, "Failed to open existing rw store\n"); + tcert1 = CertEnumCertificatesInStore(tstore, NULL); + todo_wine + ok(tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, "cert1 wasn't saved\n"); + CertFreeCertificateContext(tcert1); + CertCloseStore(tstore,0); + + tstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, WineTestRW2_W); + ok (tstore!=NULL, "Failed to open existing rw2 store\n"); + tcert1 = CertEnumCertificatesInStore(tstore, NULL); + todo_wine + ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded, "cert2 wasn't saved\n"); + CertFreeCertificateContext(tcert1); + CertCloseStore(tstore,0); + + /* now closing stores, certs are only then saved */ + CertCloseStore(collection,0); + CertCloseStore(ro_store,0); + CertCloseStore(rw_store,0); + CertCloseStore(rw_store_2,0); + + /* reopening registry stores to check whether certs had been saved (they should be this time)*/ + rw_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW_W); + tcert1 = CertEnumCertificatesInStore(rw_store, NULL); + ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, + "Unexpected cert in store %p\n", tcert1); + CertFreeCertificateContext(tcert1); + CertCloseStore(rw_store,0); + + rw_store_2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW2_W); + tcert1 = CertEnumCertificatesInStore(rw_store_2, NULL); + ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded, + "Unexpected cert in store %p\n", tcert1); + CertFreeCertificateContext(tcert1); + CertCloseStore(rw_store_2,0); + + CertFreeCertificateContext(cert1); + CertFreeCertificateContext(cert2); + CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRO_W); + CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRW_W); + CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRW2_W); + } + +} + static void testCollectionStore(void) { HCERTSTORE store1, store2, collection, collection2; @@ -2812,6 +3026,9 @@ START_TEST(store) /* various combinations of CertOpenStore */ testMemStore(); testCollectionStore(); + testStoresInCollection(); + testRootStoresInCollection(); + testRegStore(); testSystemRegStore(); testSystemStore(); -- 2.7.4 From donat at enikeev.net Tue Oct 18 07:59:54 2016 From: donat at enikeev.net (Donat Enikeev) Date: Tue, 18 Oct 2016 15:59:54 +0300 Subject: [PATCH 2/2] crypt32: return collection of registry store and systems certs store (read-only) on opening HKLM\Root store Message-ID: <1476795594-5877-1-git-send-email-donat@enikeev.net> Fixes bug: https://bugs.winehq.org/show_bug.cgi?id=30187 Follows discussion with Jacek Caban @wine-devel Signed-off-by: Donat Enikeev --- dlls/crypt32/store.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c index d5d7443..be9e5c4 100644 --- a/dlls/crypt32/store.c +++ b/dlls/crypt32/store.c @@ -412,7 +412,7 @@ static WINECRYPT_CERTSTORE *CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv, static const WCHAR fmt[] = { '%','s','\\','%','s',0 }; LPCWSTR storeName = pvPara; LPWSTR storePath; - WINECRYPT_CERTSTORE *store = NULL; + WINECRYPT_CERTSTORE *store = NULL, *env_root_store = NULL, *root_collection = NULL; HKEY root; LPCWSTR base; @@ -430,9 +430,6 @@ static WINECRYPT_CERTSTORE *CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv, * Wine's registry doesn't implement access controls, so a similar * mechanism isn't possible yet. */ - if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) == - CERT_SYSTEM_STORE_LOCAL_MACHINE && !lstrcmpiW(storeName, rootW)) - return CRYPT_RootOpenStore(hCryptProv, dwFlags); switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) { @@ -509,6 +506,43 @@ static WINECRYPT_CERTSTORE *CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv, if (!rc) { store = CRYPT_RegOpenStore(hCryptProv, dwFlags, key); + /* If HKLM\Root requested, returning a collection with it + * and the root store containing systems certs + */ + if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) == + CERT_SYSTEM_STORE_LOCAL_MACHINE && !lstrcmpiW(storeName, rootW)) + { + root_collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, 0, NULL); + if (!root_collection) + ERR("Failed to initiate collection %x\n", GetLastError()); + else + { + env_root_store = CRYPT_RootOpenStore(0, dwFlags); + if (!env_root_store) + { + ERR("Failed to open root store %x\n", GetLastError()); + CertCloseStore(root_collection, 0); + } + } + + if (root_collection && env_root_store) + { + if (!CertAddStoreToCollection(root_collection, store, + CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 1) + || !CertAddStoreToCollection(root_collection, env_root_store, 0, 0)) + { + ERR("Failed to add stores, keeping using registry store only %x\n", GetLastError()); + CertCloseStore(root_collection,0); + } + else + { + CertCloseStore(store, 0); + store = root_collection; + } + /* decrementing refcount to make a collection the only owner */ + CertCloseStore(env_root_store,0); + } + } RegCloseKey(key); } else -- 2.7.4 From sebastian at fds-team.de Tue Oct 18 09:52:12 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Tue, 18 Oct 2016 16:52:12 +0200 Subject: [PATCH v2 1/2] include: Correct NTSTATUS declaration for hidsdi.h In-Reply-To: <0a8b91dc-fe4c-ae15-d5fa-17283e005a27@codeweavers.com> References: <0a8b91dc-fe4c-ae15-d5fa-17283e005a27@codeweavers.com> Message-ID: On 17.10.2016 15:58, Aric Stewart wrote: > Signed-off-by: Aric Stewart > --- > include/ddk/hidsdi.h | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) Signed-off-by: Sebastian Lackner From aric at codeweavers.com Tue Oct 18 10:07:59 2016 From: aric at codeweavers.com (Aric Stewart) Date: Tue, 18 Oct 2016 17:07:59 +0200 Subject: [PATCH] hidclass.sys: Use IoSetCompletionRoutine Message-ID: Signed-off-by: Aric Stewart --- dlls/hidclass.sys/device.c | 20 +++++++------------- dlls/hidclass.sys/main.c | 13 +++++-------- dlls/hidclass.sys/pnp.c | 10 +++++----- 3 files changed, 17 insertions(+), 26 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-hidclass.sys-Use-IoSetCompletionRoutine.txt Type: text/x-patch Size: 4977 bytes Desc: not available URL: From jacek at codeweavers.com Tue Oct 18 10:33:30 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Tue, 18 Oct 2016 17:33:30 +0200 Subject: [PATCH 1/2] taskschd: Added ITriggerCollection::Create implementation. Message-ID: <11c28a1c-c6b1-baaa-e2c0-c6978a3c4b0e@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/taskschd/task.c | 254 +++++++++++++++++++++++++++++++++++++++- dlls/taskschd/tests/scheduler.c | 18 +++ 2 files changed, 270 insertions(+), 2 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-taskschd-Added-ITriggerCollection-Create-implementati.diff Type: text/x-patch Size: 10204 bytes Desc: not available URL: From jacek at codeweavers.com Tue Oct 18 10:33:36 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Tue, 18 Oct 2016 17:33:36 +0200 Subject: [PATCH 2/2] taskschd: Added IDailyTrigger::DaysInterval property implementation. Message-ID: <71ab7d6b-3fb5-bb64-55cd-d576c7b5fd8d@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/taskschd/task.c | 19 +++++++++++++++---- dlls/taskschd/tests/scheduler.c | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-taskschd-Added-IDailyTrigger-DaysInterval-property-im.diff Type: text/x-patch Size: 3127 bytes Desc: not available URL: From sebastian at fds-team.de Tue Oct 18 10:40:26 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Tue, 18 Oct 2016 17:40:26 +0200 Subject: [PATCH] hidclass.sys: Use IoSetCompletionRoutine In-Reply-To: References: Message-ID: <5657dd33-1d94-b9c3-ba76-2b61c7fcaa01@fds-team.de> On 18.10.2016 17:07, Aric Stewart wrote: > Signed-off-by: Aric Stewart > --- > dlls/hidclass.sys/device.c | 20 +++++++------------- > dlls/hidclass.sys/main.c | 13 +++++-------- > dlls/hidclass.sys/pnp.c | 10 +++++----- > 3 files changed, 17 insertions(+), 26 deletions(-) Thanks! While you are just at it, could you please also check the two occurances of "if (irp->IoStatus.u.Status == STATUS_PENDING)"? They look wrong to me, the correct way would be to check the return value of IoCallDriver. Also, it looks like call_minidriver is leaking "buffer". Signed-off-by: Sebastian Lackner From jacek at codeweavers.com Tue Oct 18 12:34:18 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Tue, 18 Oct 2016 19:34:18 +0200 Subject: kernel32: Improved GetUserPreferredUILanguages stub. Message-ID: Implementation and tests are based on GetSystemPreferredUILanguages. Signed-off-by: Jacek Caban --- dlls/kernel32/locale.c | 35 ++++++++--- dlls/kernel32/tests/locale.c | 140 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+), 9 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-kernel32-Improved-GetUserPreferredUILanguages-stub.diff Type: text/x-patch Size: 8901 bytes Desc: not available URL: From jacek at codeweavers.com Tue Oct 18 13:00:12 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Tue, 18 Oct 2016 20:00:12 +0200 Subject: [PATCH v2] kernel32: Improved GetUserPreferredUILanguages stub. Message-ID: <9f73a960-65a6-7e65-7778-741a0ba71f1b@codeweavers.com> v2: Rebased on clean Wine tree. Implementation and tests are based on GetSystemPreferredUILanguages. Signed-off-by: Jacek Caban --- dlls/kernel32/locale.c | 35 ++++++++--- dlls/kernel32/tests/locale.c | 140 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+), 9 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-kernel32-Improved-GetUserPreferredUILanguages-stub.diff Type: text/x-patch Size: 8833 bytes Desc: not available URL: From pierre at reactos.org Tue Oct 18 13:16:16 2016 From: pierre at reactos.org (Pierre Schweitzer) Date: Tue, 18 Oct 2016 20:16:16 +0200 Subject: [PATCH] mpr: Implement connected resources enumeration. (resend) Message-ID: As the patch was silently dropped, resending. -- Pierre Schweitzer System & Network Administrator Senior Kernel Developer ReactOS Deutschland e.V. -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-mpr-Implement-connected-resources-enumeration.patch Type: text/x-patch Size: 10719 bytes Desc: not available URL: From austinenglish at gmail.com Wed Oct 19 00:42:41 2016 From: austinenglish at gmail.com (Austin English) Date: Wed, 19 Oct 2016 00:42:41 -0500 Subject: [PATCH 1/2] shell32: add SHRemoveLocalizedName stub (try 3) Message-ID: <22499a3c-2385-8a90-6816-4062869fac0b@gmail.com> -- -Austin GPG: 14FB D7EA A041 937B -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-shell32-add-SHRemoveLocalizedName-stub-try-3.patch Type: text/x-patch Size: 1611 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 837 bytes Desc: OpenPGP digital signature URL: From austinenglish at gmail.com Wed Oct 19 00:43:12 2016 From: austinenglish at gmail.com (Austin English) Date: Wed, 19 Oct 2016 00:43:12 -0500 Subject: [PATCH 2/2] shell32: add SHCreateSessionKey stub (try 3) Message-ID: -- -Austin GPG: 14FB D7EA A041 937B -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-shell32-add-SHCreateSessionKey-stub-try-3.patch Type: text/x-patch Size: 2752 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 837 bytes Desc: OpenPGP digital signature URL: From austinenglish at gmail.com Wed Oct 19 01:12:26 2016 From: austinenglish at gmail.com (Austin English) Date: Wed, 19 Oct 2016 01:12:26 -0500 Subject: api-ms-win-core-rtlsupport-l1-1-0: add missing forwards Message-ID: <63eddd65-ce62-c2d1-4f16-1edbb13ea625@gmail.com> https://bugs.winehq.org/show_bug.cgi?id=41570 -- -Austin GPG: 14FB D7EA A041 937B -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-api-ms-win-core-rtlsupport-l1-1-0-add-missing-forwar.patch Type: text/x-patch Size: 1985 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 837 bytes Desc: OpenPGP digital signature URL: From austinenglish at gmail.com Wed Oct 19 01:17:54 2016 From: austinenglish at gmail.com (Austin English) Date: Wed, 19 Oct 2016 01:17:54 -0500 Subject: api-ms-win-core-rtlsupport-l1-1-0: add missing forwards In-Reply-To: <63eddd65-ce62-c2d1-4f16-1edbb13ea625@gmail.com> References: <63eddd65-ce62-c2d1-4f16-1edbb13ea625@gmail.com> Message-ID: <3114c0f8-91d0-74c4-c5df-a473e1c46ebd@gmail.com> On 10/19/2016 01:12 AM, Austin English wrote: > https://bugs.winehq.org/show_bug.cgi?id=41570 > So, I wrote this patch based on http://www.geoffchappell.com/studies/windows/win32/apisetschema/api/ms/win/core/rtlsupport/l1-1-0.htm, until seeing that the dll name was wrong on the bug, it's 1-1-1. This patch itself may or may not be worth committing. It doesn't match what I see on my win7/10 installations, but since Geoff has them documented, seems like they were shipped in some version of the dll. That's up to you Alexandre. -- -Austin GPG: 14FB D7EA A041 937B -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 837 bytes Desc: OpenPGP digital signature URL: From austinenglish at gmail.com Wed Oct 19 01:28:10 2016 From: austinenglish at gmail.com (Austin English) Date: Wed, 19 Oct 2016 01:28:10 -0500 Subject: api-ms-win-core-rtlsupport-l1-1-0: add missing forwards In-Reply-To: <3114c0f8-91d0-74c4-c5df-a473e1c46ebd@gmail.com> References: <63eddd65-ce62-c2d1-4f16-1edbb13ea625@gmail.com> <3114c0f8-91d0-74c4-c5df-a473e1c46ebd@gmail.com> Message-ID: On 10/19/2016 01:17 AM, Austin English wrote: > On 10/19/2016 01:12 AM, Austin English wrote: >> https://bugs.winehq.org/show_bug.cgi?id=41570 >> > > So, I wrote this patch based on > http://www.geoffchappell.com/studies/windows/win32/apisetschema/api/ms/win/core/rtlsupport/l1-1-0.htm, > until seeing that the dll name was wrong on the bug, it's 1-1-1. > > This patch itself may or may not be worth committing. It doesn't match > what I see on my win7/10 installations, but since Geoff has them > documented, seems like they were shipped in some version of the dll. > That's up to you Alexandre. Actually, looks like the log wasn't in append mode and was mangled. Does appear to be 1-1-0: https://bugs.winehq.org/attachment.cgi?id=55730 PE 7fa54eeaf000- 7fa54f0c2000 Deferred api-ms-win-core-rtlsupport-l1-1- PE 7fa54eeb0000- 7fa54f0c2000 Deferred api-ms-win-core-rtlsupport-l1-1-C:\windows\system32\api-ms-win-core-rtlsupport-l1-1-0.dll -- -Austin GPG: 14FB D7EA A041 937B -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 837 bytes Desc: OpenPGP digital signature URL: From marcus at jet.franken.de Wed Oct 19 02:22:48 2016 From: marcus at jet.franken.de (Marcus Meissner) Date: Wed, 19 Oct 2016 09:22:48 +0200 Subject: [PATCH] explorer: check icon for NULL (Coverity) Message-ID: <20161019072248.28267-1-marcus@jet.franken.de> 1373719 Dereference after null check Signed-off-by: Marcus Meissner --- programs/explorer/systray.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/programs/explorer/systray.c b/programs/explorer/systray.c index b3c192a..2c49082 100644 --- a/programs/explorer/systray.c +++ b/programs/explorer/systray.c @@ -588,8 +588,11 @@ static BOOL handle_incoming(HWND hwndSource, COPYDATASTRUCT *cds) if (icon) ret = modify_icon( icon, &nid ); break; case NIM_SETVERSION: - icon->version = nid.u.uVersion; - ret = TRUE; + if (icon) + { + icon->version = nid.u.uVersion; + ret = TRUE; + } break; default: WINE_FIXME("unhandled tray message: %ld\n", cds->dwData); -- 2.10.1 From marcus at jet.franken.de Wed Oct 19 02:26:00 2016 From: marcus at jet.franken.de (Marcus Meissner) Date: Wed, 19 Oct 2016 09:26:00 +0200 Subject: [PATCH] riched20: swap check for NULL ptr and first usage (Coverity) Message-ID: <20161019072600.10385-1-marcus@jet.franken.de> 1373721 Dereference before null check Signed-off-by: Marcus Meissner --- dlls/riched20/para.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index 3f54fea..6c023f2 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -156,7 +156,7 @@ static ME_String *para_num_get_str( ME_Paragraph *para, WORD num ) { /* max 4 Roman letters (representing '8') / decade + '(' + ')' */ ME_String *str = ME_MakeStringEmpty( 20 + 2 ); - WCHAR *p = str->szData; + WCHAR *p; static const WCHAR fmtW[] = {'%', 'd', 0}; static const WORD letter_base[] = { 1, 26, 26 * 26, 26 * 26 * 26 }; /* roman_base should start on a '5' not a '1', otherwise the 'total' code will need adjusting. @@ -177,6 +177,8 @@ static ME_String *para_num_get_str( ME_Paragraph *para, WORD num ) if (!str) return NULL; + p = str->szData; + if ((para->fmt.wNumberingStyle & 0xf00) == PFNS_PARENS) *p++ = '('; -- 2.10.1 From wine.dev at web.de Wed Oct 19 05:53:24 2016 From: wine.dev at web.de (Detlef Riekenberg) Date: Wed, 19 Oct 2016 12:53:24 +0200 Subject: [PATCH] winspool: Add our driver for all usable Printer environments Message-ID: <1476874404-6409-1-git-send-email-wine.dev@web.de> -- bye bye ... Detlef Signed-off-by: Detlef Riekenberg --- dlls/winspool.drv/info.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c index 4dea531..2f0ff3d 100644 --- a/dlls/winspool.drv/info.c +++ b/dlls/winspool.drv/info.c @@ -583,31 +583,38 @@ WINSPOOL_SetDefaultPrinter(const char *devname, const char *name, BOOL force) { static BOOL add_printer_driver(const WCHAR *name, WCHAR *ppd) { DRIVER_INFO_3W di3; + unsigned int i; + BOOL res; ZeroMemory(&di3, sizeof(DRIVER_INFO_3W)); di3.cVersion = 3; di3.pName = (WCHAR*)name; - di3.pEnvironment = envname_x86W; di3.pDriverPath = driver_nt; di3.pDataFile = ppd; di3.pConfigFile = driver_nt; di3.pDefaultDataType = rawW; - if (AddPrinterDriverExW( NULL, 3, (LPBYTE)&di3, APD_COPY_NEW_FILES | APD_COPY_FROM_DIRECTORY ) || - (GetLastError() == ERROR_PRINTER_DRIVER_ALREADY_INSTALLED )) + for (i = 0; i < sizeof(all_printenv)/sizeof(all_printenv[0]); i++) { - di3.cVersion = 0; - di3.pEnvironment = envname_win40W; - di3.pDriverPath = driver_9x; - di3.pConfigFile = driver_9x; - if (AddPrinterDriverExW( NULL, 3, (LPBYTE)&di3, APD_COPY_NEW_FILES | APD_COPY_FROM_DIRECTORY ) || - (GetLastError() == ERROR_PRINTER_DRIVER_ALREADY_INSTALLED )) + di3.pEnvironment = (WCHAR *) all_printenv[i]->envname; + if (all_printenv[i]->envname == envname_win40W) { - return TRUE; + /* We use wineps16.drv as driver for 16 bit */ + di3.pDriverPath = driver_9x; + di3.pConfigFile = driver_9x; + } + res = AddPrinterDriverExW( NULL, 3, (LPBYTE)&di3, APD_COPY_NEW_FILES | APD_COPY_FROM_DIRECTORY ); + TRACE("got %d and %d for %s (%s)\n", res, GetLastError(), debugstr_w(name), debugstr_w(di3.pEnvironment)); + + if (!res & (GetLastError() != ERROR_PRINTER_DRIVER_ALREADY_INSTALLED)) + { + ERR("failed with %u for %s (%s) %s\n", GetLastError(), debugstr_w(name), + debugstr_w(di3.pEnvironment), debugstr_w(di3.pDriverPath)); + return FALSE; } } - ERR("failed with %u for %s (%s)\n", GetLastError(), debugstr_w(di3.pDriverPath), debugstr_w(di3.pEnvironment)); - return FALSE; + + return TRUE; } static inline char *expand_env_string( char *str, DWORD type ) -- 2.7.4 From sebastian at fds-team.de Wed Oct 19 06:02:26 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Wed, 19 Oct 2016 13:02:26 +0200 Subject: [PATCH 1/2] shell32: add SHRemoveLocalizedName stub (try 3) In-Reply-To: <22499a3c-2385-8a90-6816-4062869fac0b@gmail.com> References: <22499a3c-2385-8a90-6816-4062869fac0b@gmail.com> Message-ID: <1a134969-35ad-f0fa-ffe8-5ff8fe9c7461@fds-team.de> On 19.10.2016 07:42, Austin English wrote: > -- -Austin GPG: 14FB D7EA A041 937B > > > 0001-shell32-add-SHRemoveLocalizedName-stub-try-3.patch > > > From de58cb82b9d104fe2fa9d469f3dfa58e6771668c Mon Sep 17 00:00:00 2001 > From: Austin English > Date: Mon, 10 Oct 2016 21:46:26 -0500 > Subject: [PATCH 1/2] shell32: add SHRemoveLocalizedName stub (try 3) > > Signed-off-by: Austin English > --- > dlls/shell32/shell32.spec | 1 + > dlls/shell32/shellord.c | 9 +++++++++ > 2 files changed, 10 insertions(+) > Signed-off-by: Sebastian Lackner From sebastian at fds-team.de Wed Oct 19 06:07:33 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Wed, 19 Oct 2016 13:07:33 +0200 Subject: shell32: Add SHCreateSessionKey stub. (v4) Message-ID: <507380f5-2d18-b097-b2f3-83423872cf70@fds-team.de> From: Austin English Signed-off-by: Austin English Signed-off-by: Sebastian Lackner --- Changes in v4: * Mark function as -noname (sorry, I missed that in the earlier review). dlls/shell32/shell32.spec | 1 + dlls/shell32/shellreg.c | 11 +++++++++++ dlls/shell32/tests/shellole.c | 10 +++++----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec index 0d43f3b..cd4f24a 100644 --- a/dlls/shell32/shell32.spec +++ b/dlls/shell32/shell32.spec @@ -261,6 +261,7 @@ 704 stdcall -noname GUIDFromStringW(wstr ptr) 709 stdcall SHGetSetFolderCustomSettings(ptr str long) 714 stdcall @(ptr) SHELL32_714 # PathIsTemporaryW + 723 stdcall -noname SHCreateSessionKey(long ptr) 727 stdcall SHGetImageList(long ptr ptr) 730 stdcall -noname RestartDialogEx(long wstr long long) 743 stdcall SHCreateFileExtractIconW(wstr long ptr ptr) diff --git a/dlls/shell32/shellreg.c b/dlls/shell32/shellreg.c index 37f3d9e..356ec4e 100644 --- a/dlls/shell32/shellreg.c +++ b/dlls/shell32/shellreg.c @@ -147,3 +147,14 @@ HRESULT WINAPI SHRegCloseKey (HKEY hkey) TRACE("%p\n",hkey); return RegCloseKey( hkey ); } + +/************************************************************************* + * SHCreateSessionKey [SHELL32.723] + * + */ +HRESULT WINAPI SHCreateSessionKey(REGSAM access, HKEY *hkey) +{ + FIXME("stub: %d %p\n", access, hkey); + *hkey = NULL; + return E_NOTIMPL; +} diff --git a/dlls/shell32/tests/shellole.c b/dlls/shell32/tests/shellole.c index 04c9632..be10733 100644 --- a/dlls/shell32/tests/shellole.c +++ b/dlls/shell32/tests/shellole.c @@ -867,7 +867,7 @@ static void test_SHCreateSessionKey(void) if (!pSHCreateSessionKey) { - skip("SHCreateSessionKey is not implemented\n"); + win_skip("SHCreateSessionKey is not implemented\n"); return; } @@ -876,15 +876,15 @@ static void test_SHCreateSessionKey(void) hkey = (HKEY)0xdeadbeef; hr = pSHCreateSessionKey(0, &hkey); - ok(hr == E_ACCESSDENIED, "got 0x%08x\n", hr); + todo_wine ok(hr == E_ACCESSDENIED, "got 0x%08x\n", hr); ok(hkey == NULL, "got %p\n", hkey); hr = pSHCreateSessionKey(KEY_READ, &hkey); - ok(hr == S_OK, "got 0x%08x\n", hr); + todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); hr = pSHCreateSessionKey(KEY_READ, &hkey2); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(hkey != hkey2, "got %p, %p\n", hkey, hkey2); + todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); + todo_wine ok(hkey != hkey2, "got %p, %p\n", hkey, hkey2); RegCloseKey(hkey); RegCloseKey(hkey2); -- 2.9.0 From hverbeet at codeweavers.com Wed Oct 19 06:32:04 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Wed, 19 Oct 2016 13:32:04 +0200 Subject: [PATCH 1/6] wined3d: Let buffer_direct_upload() invalidate STATE_INDEXBUFFER if needed. In-Reply-To: <1476647209-11162-1-git-send-email-jkucia@codeweavers.com> References: <1476647209-11162-1-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Wed Oct 19 06:32:05 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Wed, 19 Oct 2016 13:32:05 +0200 Subject: [PATCH 2/6] wined3d: Clean up buffer_internal_preload(). In-Reply-To: <1476647209-11162-2-git-send-email-jkucia@codeweavers.com> References: <1476647209-11162-2-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Wed Oct 19 06:32:05 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Wed, 19 Oct 2016 13:32:05 +0200 Subject: [PATCH 3/6] wined3d: Rename buffer_internal_preload() to wined3d_buffer_load(). In-Reply-To: <1476647209-11162-3-git-send-email-jkucia@codeweavers.com> References: <1476647209-11162-3-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Wed Oct 19 06:32:06 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Wed, 19 Oct 2016 13:32:06 +0200 Subject: [PATCH 4/6] wined3d: Rename buffer_get_sysmem() to wined3d_buffer_load_sysmem(). In-Reply-To: <1476647209-11162-4-git-send-email-jkucia@codeweavers.com> References: <1476647209-11162-4-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Wed Oct 19 06:32:07 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Wed, 19 Oct 2016 13:32:07 +0200 Subject: [PATCH 5/6] wined3d: Explicitly track locations for buffers. In-Reply-To: <1476647209-11162-5-git-send-email-jkucia@codeweavers.com> References: <1476647209-11162-5-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From matellanesivan at gmail.com Wed Oct 19 07:00:51 2016 From: matellanesivan at gmail.com (=?UTF-8?q?Iv=C3=A1n=20Matellanes?=) Date: Wed, 19 Oct 2016 14:00:51 +0200 Subject: [1/6] msvcirt: Don't return negative values in in_avail and out_waiting. Message-ID: <1476878456-8303-1-git-send-email-matellanesivan@gmail.com> Signed-off-by: Iván Matellanes --- dlls/msvcirt/msvcirt.c | 4 ++-- dlls/msvcirt/tests/msvcirt.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index 8dfe988..e9103a9 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -556,7 +556,7 @@ DEFINE_THISCALL_WRAPPER(streambuf_in_avail, 4) int __thiscall streambuf_in_avail(const streambuf *this) { TRACE("(%p)\n", this); - return this->egptr - this->gptr; + return (this->egptr - this->gptr > 0) ? this->egptr - this->gptr : 0; } /* ?out_waiting at streambuf@@QBEHXZ */ @@ -565,7 +565,7 @@ DEFINE_THISCALL_WRAPPER(streambuf_out_waiting, 4) int __thiscall streambuf_out_waiting(const streambuf *this) { TRACE("(%p)\n", this); - return this->pptr - this->pbase; + return (this->pptr - this->pbase > 0) ? this->pptr - this->pbase : 0; } /* Unexported */ diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c index 113bf0e..7f25cd7 100644 --- a/dlls/msvcirt/tests/msvcirt.c +++ b/dlls/msvcirt/tests/msvcirt.c @@ -200,7 +200,9 @@ static int (*__thiscall p_streambuf_allocate)(streambuf*); static void (*__thiscall p_streambuf_clrclock)(streambuf*); static int (*__thiscall p_streambuf_doallocate)(streambuf*); static void (*__thiscall p_streambuf_gbump)(streambuf*, int); +static int (*__thiscall p_streambuf_in_avail)(const streambuf*); static void (*__thiscall p_streambuf_lock)(streambuf*); +static int (*__thiscall p_streambuf_out_waiting)(const streambuf*); static int (*__thiscall p_streambuf_pbackfail)(streambuf*, int); static void (*__thiscall p_streambuf_pbump)(streambuf*, int); static int (*__thiscall p_streambuf_sbumpc)(streambuf*); @@ -480,7 +482,9 @@ static BOOL init(void) SET(p_streambuf_clrclock, "?clrlock at streambuf@@QEAAXXZ"); SET(p_streambuf_doallocate, "?doallocate at streambuf@@MEAAHXZ"); SET(p_streambuf_gbump, "?gbump at streambuf@@IEAAXH at Z"); + SET(p_streambuf_in_avail, "?in_avail at streambuf@@QEBAHXZ"); SET(p_streambuf_lock, "?lock at streambuf@@QEAAXXZ"); + SET(p_streambuf_out_waiting, "?out_waiting at streambuf@@QEBAHXZ"); SET(p_streambuf_pbackfail, "?pbackfail at streambuf@@UEAAHH at Z"); SET(p_streambuf_pbump, "?pbump at streambuf@@IEAAXH at Z"); SET(p_streambuf_sbumpc, "?sbumpc at streambuf@@QEAAHXZ"); @@ -657,7 +661,9 @@ static BOOL init(void) SET(p_streambuf_clrclock, "?clrlock at streambuf@@QAEXXZ"); SET(p_streambuf_doallocate, "?doallocate at streambuf@@MAEHXZ"); SET(p_streambuf_gbump, "?gbump at streambuf@@IAEXH at Z"); + SET(p_streambuf_in_avail, "?in_avail at streambuf@@QBEHXZ"); SET(p_streambuf_lock, "?lock at streambuf@@QAEXXZ"); + SET(p_streambuf_out_waiting, "?out_waiting at streambuf@@QBEHXZ"); SET(p_streambuf_pbackfail, "?pbackfail at streambuf@@UAEHH at Z"); SET(p_streambuf_pbump, "?pbump at streambuf@@IAEXH at Z"); SET(p_streambuf_sbumpc, "?sbumpc at streambuf@@QAEHXZ"); @@ -1388,6 +1394,36 @@ static void test_streambuf(void) ok(sb2.gptr == sb2.egptr, "wrong get pointer, expected %p got %p\n", sb2.egptr, sb2.gptr); ok(*sb2.gptr == 'X', "expected 'X' in the get area, got %c\n", *sb2.gptr); + /* out_waiting */ + ret = (int) call_func1(p_streambuf_out_waiting, &sb); + ok(ret == 9, "expected 9 got %d\n", ret); + sb.pptr = sb.pbase; + ret = (int) call_func1(p_streambuf_out_waiting, &sb); + ok(ret == 0, "expected 0 got %d\n", ret); + sb.pptr = sb.pbase - 1; + ret = (int) call_func1(p_streambuf_out_waiting, &sb); + ok(ret == 0, "expected 0 got %d\n", ret); + sb.pptr = NULL; + ret = (int) call_func1(p_streambuf_out_waiting, &sb); + ok(ret == 0, "expected 0 got %d\n", ret); + sb.pptr = sb.epptr; + sb.pbase = NULL; + ret = (int) call_func1(p_streambuf_out_waiting, &sb); + ok(ret == (int)(sb.pptr - sb.pbase), "expected %d got %d\n", (int)(sb.pptr - sb.pbase), ret); + + /* in_avail */ + ret = (int) call_func1(p_streambuf_in_avail, &sb); + ok(ret == 256, "expected 256 got %d\n", ret); + sb.gptr = sb.egptr; + ret = (int) call_func1(p_streambuf_in_avail, &sb); + ok(ret == 0, "expected 0 got %d\n", ret); + sb.gptr = sb.egptr + 1; + ret = (int) call_func1(p_streambuf_in_avail, &sb); + ok(ret == 0, "expected 0 got %d\n", ret); + sb.egptr = NULL; + ret = (int) call_func1(p_streambuf_in_avail, &sb); + ok(ret == 0, "expected 0 got %d\n", ret); + SetEvent(lock_arg.test[3]); WaitForSingleObject(thread, INFINITE); -- 2.7.4 From matellanesivan at gmail.com Wed Oct 19 07:00:53 2016 From: matellanesivan at gmail.com (=?UTF-8?q?Iv=C3=A1n=20Matellanes?=) Date: Wed, 19 Oct 2016 14:00:53 +0200 Subject: [3/6] msvcirt: Implement ostrstream constructors. In-Reply-To: <1476878456-8303-1-git-send-email-matellanesivan@gmail.com> References: <1476878456-8303-1-git-send-email-matellanesivan@gmail.com> Message-ID: <1476878456-8303-3-git-send-email-matellanesivan@gmail.com> Signed-off-by: Iván Matellanes --- dlls/msvcirt/msvcirt.c | 39 +++++- dlls/msvcirt/tests/msvcirt.c | 287 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 321 insertions(+), 5 deletions(-) diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index ebbe442..ffa7b93 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -2951,12 +2951,28 @@ ostream* __thiscall ostream_withassign_ctor(ostream *this, BOOL virt_init) return this; } +static ostream* ostrstream_internal_sb_ctor(ostream *this, strstreambuf *ssb, BOOL virt_init) +{ + ios *base; + + if (ssb) + ostream_sb_ctor(this, &ssb->base, virt_init); + else + ostream_ctor(this, virt_init); + base = ostream_get_ios(this); + base->vtable = &MSVCP_ostrstream_vtable; + base->delbuf = 1; + return this; +} + /* ??0ostrstream@@QAE at ABV0@@Z */ /* ??0ostrstream@@QEAA at AEBV0@@Z */ DEFINE_THISCALL_WRAPPER(ostrstream_copy_ctor, 12) ostream* __thiscall ostrstream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init) { - FIXME("(%p %p %d) stub\n", this, copy, virt_init); + TRACE("(%p %p %d)\n", this, copy, virt_init); + ostream_withassign_copy_ctor(this, copy, virt_init); + ostream_get_ios(this)->vtable = &MSVCP_ostrstream_vtable; return this; } @@ -2965,8 +2981,16 @@ ostream* __thiscall ostrstream_copy_ctor(ostream *this, const ostream *copy, BOO DEFINE_THISCALL_WRAPPER(ostrstream_buffer_ctor, 20) ostream* __thiscall ostrstream_buffer_ctor(ostream *this, char *buffer, int length, int mode, BOOL virt_init) { - FIXME("(%p %p %d %d %d) stub\n", this, buffer, length, mode, virt_init); - return this; + strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf)); + + TRACE("(%p %p %d %d %d)\n", this, buffer, length, mode, virt_init); + + if (ssb) { + strstreambuf_buffer_ctor(ssb, buffer, length, buffer); + if (mode & (OPENMODE_app|OPENMODE_ate)) + ssb->base.pptr = buffer + strlen(buffer); + } + return ostrstream_internal_sb_ctor(this, ssb, virt_init); } /* ??0ostrstream@@QAE at XZ */ @@ -2974,8 +2998,13 @@ ostream* __thiscall ostrstream_buffer_ctor(ostream *this, char *buffer, int leng DEFINE_THISCALL_WRAPPER(ostrstream_ctor, 8) ostream* __thiscall ostrstream_ctor(ostream *this, BOOL virt_init) { - FIXME("(%p %d) stub\n", this, virt_init); - return this; + strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf)); + + TRACE("(%p %d)\n", this, virt_init); + + if (ssb) + strstreambuf_ctor(ssb); + return ostrstream_internal_sb_ctor(this, ssb, virt_init); } /* ?pcount at ostrstream@@QBEHXZ */ diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c index 7f25cd7..e656866 100644 --- a/dlls/msvcirt/tests/msvcirt.c +++ b/dlls/msvcirt/tests/msvcirt.c @@ -329,6 +329,14 @@ static ostream* (*__thiscall p_ostream_withassign_assign_sb)(ostream*, streambuf static ostream* (*__thiscall p_ostream_withassign_assign_os)(ostream*, const ostream*); static ostream* (*__thiscall p_ostream_withassign_assign)(ostream*, const ostream*); +/* ostrstream */ +static ostream* (*__thiscall p_ostrstream_copy_ctor)(ostream*, const ostream*, BOOL); +static ostream* (*__thiscall p_ostrstream_buffer_ctor)(ostream*, char*, int, int, BOOL); +static ostream* (*__thiscall p_ostrstream_ctor)(ostream*, BOOL); +static void (*__thiscall p_ostrstream_dtor)(ios*); +static void (*__thiscall p_ostrstream_vbase_dtor)(ostream*); +static ostream* (*__thiscall p_ostrstream_assign)(ostream*, const ostream*); + /* istream */ static istream* (*__thiscall p_istream_copy_ctor)(istream*, const istream*, BOOL); static istream* (*__thiscall p_istream_ctor)(istream*, BOOL); @@ -594,6 +602,13 @@ static BOOL init(void) SET(p_ostream_withassign_assign_os, "??4ostream_withassign@@QEAAAEAVostream@@AEBV1@@Z"); SET(p_ostream_withassign_assign, "??4ostream_withassign@@QEAAAEAV0 at AEBV0@@Z"); + SET(p_ostrstream_copy_ctor, "??0ostrstream@@QEAA at AEBV0@@Z"); + SET(p_ostrstream_buffer_ctor, "??0ostrstream@@QEAA at PEADHH@Z"); + SET(p_ostrstream_ctor, "??0ostrstream@@QEAA at XZ"); + SET(p_ostrstream_dtor, "??1ostrstream@@UEAA at XZ"); + SET(p_ostrstream_vbase_dtor, "??_Dostrstream@@QEAAXXZ"); + SET(p_ostrstream_assign, "??4ostrstream@@QEAAAEAV0 at AEBV0@@Z"); + SET(p_istream_copy_ctor, "??0istream@@IEAA at AEBV0@@Z"); SET(p_istream_ctor, "??0istream@@IEAA at XZ"); SET(p_istream_sb_ctor, "??0istream@@QEAA at PEAVstreambuf@@@Z"); @@ -773,6 +788,13 @@ static BOOL init(void) SET(p_ostream_withassign_assign_os, "??4ostream_withassign@@QAEAAVostream@@ABV1@@Z"); SET(p_ostream_withassign_assign, "??4ostream_withassign@@QAEAAV0 at ABV0@@Z"); + SET(p_ostrstream_copy_ctor, "??0ostrstream@@QAE at ABV0@@Z"); + SET(p_ostrstream_buffer_ctor, "??0ostrstream@@QAE at PADHH@Z"); + SET(p_ostrstream_ctor, "??0ostrstream@@QAE at XZ"); + SET(p_ostrstream_dtor, "??1ostrstream@@UAE at XZ"); + SET(p_ostrstream_vbase_dtor, "??_Dostrstream@@QAEXXZ"); + SET(p_ostrstream_assign, "??4ostrstream@@QAEAAV0 at ABV0@@Z"); + SET(p_istream_copy_ctor, "??0istream@@IAE at ABV0@@Z"); SET(p_istream_ctor, "??0istream@@IAE at XZ"); SET(p_istream_sb_ctor, "??0istream@@QAE at PAVstreambuf@@@Z"); @@ -3969,6 +3991,270 @@ static void test_ostream_withassign(void) ok(osa1.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, osa1.base_ios.do_lock); } +static void test_ostrstream(void) +{ + ostream os1, os2, *pos, *pos2; + strstreambuf *pssb; + char buffer[32]; + + memset(&os1, 0xab, sizeof(ostream)); + memset(&os2, 0xab, sizeof(ostream)); + + /* constructors/destructors */ + pos = call_func2(p_ostrstream_ctor, &os1, TRUE); + pssb = (strstreambuf*) os1.base_ios.sb; + ok(pos == &os1, "wrong return, expected %p got %p\n", &os1, pos); + ok(os1.unknown == 0, "expected 0 got %d\n", os1.unknown); + ok(os1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, os1.base_ios.sb); + ok(os1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, os1.base_ios.state); + ok(os1.base_ios.delbuf == 1, "expected 1 got %d\n", os1.base_ios.delbuf); + ok(os1.base_ios.tie == NULL, "expected %p got %p\n", NULL, os1.base_ios.tie); + ok(os1.base_ios.flags == 0, "expected 0 got %x\n", os1.base_ios.flags); + ok(os1.base_ios.precision == 6, "expected 6 got %d\n", os1.base_ios.precision); + ok(os1.base_ios.fill == ' ', "expected 32 got %d\n", os1.base_ios.fill); + ok(os1.base_ios.width == 0, "expected 0 got %d\n", os1.base_ios.width); + ok(os1.base_ios.do_lock == -1, "expected -1 got %d\n", os1.base_ios.do_lock); + ok(pssb->dynamic == 1, "expected 1, got %d\n", pssb->dynamic); + ok(pssb->increase == 1, "expected 1, got %d\n", pssb->increase); + ok(pssb->constant == 0, "expected 0, got %d\n", pssb->constant); + ok(pssb->f_alloc == NULL, "expected %p, got %p\n", NULL, pssb->f_alloc); + ok(pssb->f_free == NULL, "expected %p, got %p\n", NULL, pssb->f_free); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == NULL, "wrong buffer, expected %p got %p\n", NULL, pssb->base.base); + ok(pssb->base.ebuf == NULL, "wrong buffer end, expected %p got %p\n", NULL, pssb->base.ebuf); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_ostrstream_vbase_dtor, &os1); + ok(os1.base_ios.sb == NULL, "expected %p got %p\n", NULL, os1.base_ios.sb); + ok(os1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, os1.base_ios.state); + os1.unknown = 0xabababab; + memset(&os1.base_ios, 0xab, sizeof(ios)); + os1.base_ios.delbuf = 0; + pos = call_func2(p_ostrstream_ctor, &os1, FALSE); + pssb = (strstreambuf*) os1.base_ios.sb; + ok(pos == &os1, "wrong return, expected %p got %p\n", &os1, pos); + ok(os1.unknown == 0, "expected 0 got %d\n", os1.unknown); + ok(os1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, os1.base_ios.sb); + ok(os1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, os1.base_ios.state); + ok(os1.base_ios.delbuf == 1, "expected 1 got %d\n", os1.base_ios.delbuf); + ok(os1.base_ios.tie == os2.base_ios.tie, "expected %p got %p\n", os2.base_ios.tie, os1.base_ios.tie); + ok(os1.base_ios.flags == 0xabababab, "expected %x got %x\n", 0xabababab, os1.base_ios.flags); + ok(os1.base_ios.precision == 0xabababab, "expected %d got %d\n", 0xabababab, os1.base_ios.precision); + ok(os1.base_ios.fill == (char) 0xab, "expected -85 got %d\n", os1.base_ios.fill); + ok(os1.base_ios.width == 0xabababab, "expected %d got %d\n", 0xabababab, os1.base_ios.width); + ok(os1.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, os1.base_ios.do_lock); + ok(pssb->dynamic == 1, "expected 1, got %d\n", pssb->dynamic); + ok(pssb->increase == 1, "expected 1, got %d\n", pssb->increase); + ok(pssb->constant == 0, "expected 0, got %d\n", pssb->constant); + ok(pssb->f_alloc == NULL, "expected %p, got %p\n", NULL, pssb->f_alloc); + ok(pssb->f_free == NULL, "expected %p, got %p\n", NULL, pssb->f_free); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == NULL, "wrong buffer, expected %p got %p\n", NULL, pssb->base.base); + ok(pssb->base.ebuf == NULL, "wrong buffer end, expected %p got %p\n", NULL, pssb->base.ebuf); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_ostrstream_dtor, &os1.base_ios); + ok(os1.base_ios.sb == &pssb->base, "expected %p got %p\n", &pssb->base, os1.base_ios.sb); + ok(os1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, os1.base_ios.state); + call_func1(p_strstreambuf_dtor, pssb); + p_operator_delete(pssb); + + memset(&os1, 0xab, sizeof(ostream)); + pos = call_func5(p_ostrstream_buffer_ctor, &os1, buffer, 32, OPENMODE_in|OPENMODE_out, TRUE); + pssb = (strstreambuf*) os1.base_ios.sb; + ok(pos == &os1, "wrong return, expected %p got %p\n", &os1, pos); + ok(os1.unknown == 0, "expected 0 got %d\n", os1.unknown); + ok(os1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, os1.base_ios.sb); + ok(os1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, os1.base_ios.state); + ok(os1.base_ios.delbuf == 1, "expected 1 got %d\n", os1.base_ios.delbuf); + ok(os1.base_ios.tie == NULL, "expected %p got %p\n", NULL, os1.base_ios.tie); + ok(os1.base_ios.flags == 0, "expected 0 got %x\n", os1.base_ios.flags); + ok(os1.base_ios.precision == 6, "expected 6 got %d\n", os1.base_ios.precision); + ok(os1.base_ios.fill == ' ', "expected 32 got %d\n", os1.base_ios.fill); + ok(os1.base_ios.width == 0, "expected 0 got %d\n", os1.base_ios.width); + ok(os1.base_ios.do_lock == -1, "expected -1 got %d\n", os1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); + ok(pssb->base.ebuf == buffer + 32, "wrong buffer end, expected %p got %p\n", buffer + 32, pssb->base.ebuf); + ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); + ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); + ok(pssb->base.egptr == buffer, "wrong get end, expected %p got %p\n", buffer, pssb->base.egptr); + ok(pssb->base.pbase == buffer, "wrong put base, expected %p got %p\n", buffer, pssb->base.pbase); + ok(pssb->base.pptr == buffer, "wrong put pointer, expected %p got %p\n", buffer, pssb->base.pptr); + ok(pssb->base.epptr == buffer + 32, "wrong put end, expected %p got %p\n", buffer + 32, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_ostrstream_vbase_dtor, &os1); + ok(os1.base_ios.sb == NULL, "expected %p got %p\n", NULL, os1.base_ios.sb); + ok(os1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, os1.base_ios.state); + strcpy(buffer, "Test"); + memset(&os1, 0xab, sizeof(ostream)); + pos = call_func5(p_ostrstream_buffer_ctor, &os1, buffer, 16, OPENMODE_ate, TRUE); + pssb = (strstreambuf*) os1.base_ios.sb; + ok(pos == &os1, "wrong return, expected %p got %p\n", &os1, pos); + ok(os1.unknown == 0, "expected 0 got %d\n", os1.unknown); + ok(os1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, os1.base_ios.sb); + ok(os1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, os1.base_ios.state); + ok(os1.base_ios.delbuf == 1, "expected 1 got %d\n", os1.base_ios.delbuf); + ok(os1.base_ios.tie == NULL, "expected %p got %p\n", NULL, os1.base_ios.tie); + ok(os1.base_ios.flags == 0, "expected 0 got %x\n", os1.base_ios.flags); + ok(os1.base_ios.precision == 6, "expected 6 got %d\n", os1.base_ios.precision); + ok(os1.base_ios.fill == ' ', "expected 32 got %d\n", os1.base_ios.fill); + ok(os1.base_ios.width == 0, "expected 0 got %d\n", os1.base_ios.width); + ok(os1.base_ios.do_lock == -1, "expected -1 got %d\n", os1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); + ok(pssb->base.ebuf == buffer + 16, "wrong buffer end, expected %p got %p\n", buffer + 16, pssb->base.ebuf); + ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); + ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); + ok(pssb->base.egptr == buffer, "wrong get end, expected %p got %p\n", buffer, pssb->base.egptr); + ok(pssb->base.pbase == buffer, "wrong put base, expected %p got %p\n", buffer, pssb->base.pbase); + ok(pssb->base.pptr == buffer + 4, "wrong put pointer, expected %p got %p\n", buffer + 4, pssb->base.pptr); + ok(pssb->base.epptr == buffer + 16, "wrong put end, expected %p got %p\n", buffer + 16, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_ostrstream_vbase_dtor, &os1); + ok(os1.base_ios.sb == NULL, "expected %p got %p\n", NULL, os1.base_ios.sb); + ok(os1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, os1.base_ios.state); + os1.unknown = 0xabababab; + memset(&os1.base_ios, 0xab, sizeof(ios)); + os1.base_ios.delbuf = 0; + pos = call_func5(p_ostrstream_buffer_ctor, &os1, buffer, -1, OPENMODE_app, FALSE); + pssb = (strstreambuf*) os1.base_ios.sb; + ok(pos == &os1, "wrong return, expected %p got %p\n", &os1, pos); + ok(os1.unknown == 0, "expected 0 got %d\n", os1.unknown); + ok(os1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, os1.base_ios.sb); + ok(os1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, os1.base_ios.state); + ok(os1.base_ios.delbuf == 1, "expected 1 got %d\n", os1.base_ios.delbuf); + ok(os1.base_ios.tie == os2.base_ios.tie, "expected %p got %p\n", os2.base_ios.tie, os1.base_ios.tie); + ok(os1.base_ios.flags == 0xabababab, "expected %x got %x\n", 0xabababab, os1.base_ios.flags); + ok(os1.base_ios.precision == 0xabababab, "expected %d got %d\n", 0xabababab, os1.base_ios.precision); + ok(os1.base_ios.fill == (char) 0xab, "expected -85 got %d\n", os1.base_ios.fill); + ok(os1.base_ios.width == 0xabababab, "expected %d got %d\n", 0xabababab, os1.base_ios.width); + ok(os1.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, os1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); + ok(pssb->base.ebuf == buffer + 0x7fffffff || pssb->base.ebuf == (char*) -1, + "wrong buffer end, expected %p + 0x7fffffff or -1, got %p\n", buffer, pssb->base.ebuf); + ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); + ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); + ok(pssb->base.egptr == buffer, "wrong get end, expected %p got %p\n", buffer, pssb->base.egptr); + ok(pssb->base.pbase == buffer, "wrong put base, expected %p got %p\n", buffer, pssb->base.pbase); + ok(pssb->base.pptr == buffer + 4, "wrong put pointer, expected %p got %p\n", buffer + 4, pssb->base.pptr); + ok(pssb->base.epptr == buffer + 0x7fffffff || pssb->base.epptr == (char*) -1, + "wrong buffer end, expected %p + 0x7fffffff or -1, got %p\n", buffer, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_ostrstream_dtor, &os1.base_ios); + ok(os1.base_ios.sb == &pssb->base, "expected %p got %p\n", &pssb->base, os1.base_ios.sb); + ok(os1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, os1.base_ios.state); + call_func1(p_strstreambuf_dtor, pssb); + p_operator_delete(pssb); + memset(&os1, 0xab, sizeof(ostream)); + pos = call_func5(p_ostrstream_buffer_ctor, &os1, buffer, 0, OPENMODE_trunc, TRUE); + pssb = (strstreambuf*) os1.base_ios.sb; + ok(pos == &os1, "wrong return, expected %p got %p\n", &os1, pos); + ok(os1.unknown == 0, "expected 0 got %d\n", os1.unknown); + ok(os1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, os1.base_ios.sb); + ok(os1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, os1.base_ios.state); + ok(os1.base_ios.delbuf == 1, "expected 1 got %d\n", os1.base_ios.delbuf); + ok(os1.base_ios.tie == NULL, "expected %p got %p\n", NULL, os1.base_ios.tie); + ok(os1.base_ios.flags == 0, "expected 0 got %x\n", os1.base_ios.flags); + ok(os1.base_ios.precision == 6, "expected 6 got %d\n", os1.base_ios.precision); + ok(os1.base_ios.fill == ' ', "expected 32 got %d\n", os1.base_ios.fill); + ok(os1.base_ios.width == 0, "expected 0 got %d\n", os1.base_ios.width); + ok(os1.base_ios.do_lock == -1, "expected -1 got %d\n", os1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); + ok(pssb->base.ebuf == buffer + 4, "wrong buffer end, expected %p got %p\n", buffer + 4, pssb->base.ebuf); + ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); + ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); + ok(pssb->base.egptr == buffer, "wrong get end, expected %p got %p\n", buffer, pssb->base.egptr); + ok(pssb->base.pbase == buffer, "wrong put base, expected %p got %p\n", buffer, pssb->base.pbase); + ok(pssb->base.pptr == buffer, "wrong put pointer, expected %p got %p\n", buffer, pssb->base.pptr); + ok(pssb->base.epptr == buffer + 4, "wrong put end, expected %p got %p\n", buffer + 4, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_ostrstream_vbase_dtor, &os1); + ok(os1.base_ios.sb == NULL, "expected %p got %p\n", NULL, os1.base_ios.sb); + ok(os1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, os1.base_ios.state); + + os1.unknown = 0xcdcdcdcd; + memset(&os1.base_ios, 0xcd, sizeof(ios)); + pos = call_func3(p_ostrstream_copy_ctor, &os2, &os1, TRUE); + ok(pos == &os2, "wrong return, expected %p got %p\n", &os2, pos); + ok(os2.unknown == 0, "expected 0 got %d\n", os2.unknown); + ok(os2.base_ios.sb == os1.base_ios.sb, "expected %p got %p\n", os1.base_ios.sb, os2.base_ios.sb); + ok(os2.base_ios.state == 0xcdcdcdc9, "expected %d got %d\n", 0xcdcdcdc9, os2.base_ios.state); + ok(os2.base_ios.delbuf == 0, "expected 0 got %d\n", os2.base_ios.delbuf); + ok(os2.base_ios.tie == os1.base_ios.tie, "expected %p got %p\n", os1.base_ios.tie, os2.base_ios.tie); + ok(os2.base_ios.flags == 0xcdcdcdcd, "expected %x got %x\n", 0xcdcdcdcd, os2.base_ios.flags); + ok(os2.base_ios.precision == (char) 0xcd, "expected -51 got %d\n", os2.base_ios.precision); + ok(os2.base_ios.fill == (char) 0xcd, "expected -51 got %d\n", os2.base_ios.fill); + ok(os2.base_ios.width == (char) 0xcd, "expected -51 got %d\n", os2.base_ios.width); + ok(os2.base_ios.do_lock == -1, "expected -1 got %d\n", os2.base_ios.do_lock); + call_func1(p_ostrstream_vbase_dtor, &os2); + ok(os2.base_ios.sb == NULL, "expected %p got %p\n", NULL, os2.base_ios.sb); + ok(os2.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, os2.base_ios.state); + os2.unknown = 0xabababab; + memset(&os2.base_ios, 0xab, sizeof(ios)); + os2.base_ios.delbuf = 0; + pos2 = os2.base_ios.tie; + pos = call_func3(p_ostrstream_copy_ctor, &os2, &os1, FALSE); + ok(pos == &os2, "wrong return, expected %p got %p\n", &os2, pos); + ok(os2.unknown == 0, "expected 0 got %d\n", os2.unknown); + ok(os2.base_ios.sb == os1.base_ios.sb, "expected %p got %p\n", os1.base_ios.sb, os2.base_ios.sb); + ok(os2.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, os2.base_ios.state); + ok(os2.base_ios.delbuf == 0, "expected 0 got %d\n", os2.base_ios.delbuf); + ok(os2.base_ios.tie == pos2, "expected %p got %p\n", pos2, os2.base_ios.tie); + ok(os2.base_ios.flags == 0xabababab, "expected %x got %x\n", 0xabababab, os2.base_ios.flags); + ok(os2.base_ios.precision == 0xabababab, "expected %d got %d\n", 0xabababab, os2.base_ios.precision); + ok(os2.base_ios.fill == (char) 0xab, "expected -85 got %d\n", os2.base_ios.fill); + ok(os2.base_ios.width == 0xabababab, "expected %d got %d\n", 0xabababab, os2.base_ios.width); + ok(os2.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, os2.base_ios.do_lock); + call_func1(p_ostrstream_dtor, &os2.base_ios); + os1.base_ios.sb = NULL; + memset(&os2, 0xab, sizeof(ostream)); + pos = call_func3(p_ostrstream_copy_ctor, &os2, &os1, TRUE); + ok(pos == &os2, "wrong return, expected %p got %p\n", &os2, pos); + ok(os2.unknown == 0, "expected 0 got %d\n", os2.unknown); + ok(os2.base_ios.sb == NULL, "expected %p got %p\n", NULL, os2.base_ios.sb); + ok(os2.base_ios.state == 0xcdcdcdcd, "expected %d got %d\n", 0xcdcdcdcd, os2.base_ios.state); + ok(os2.base_ios.delbuf == 0, "expected 0 got %d\n", os2.base_ios.delbuf); + ok(os2.base_ios.tie == os1.base_ios.tie, "expected %p got %p\n", os1.base_ios.tie, os2.base_ios.tie); + ok(os2.base_ios.flags == 0xcdcdcdcd, "expected %x got %x\n", 0xcdcdcdcd, os2.base_ios.flags); + ok(os2.base_ios.precision == (char) 0xcd, "expected -51 got %d\n", os2.base_ios.precision); + ok(os2.base_ios.fill == (char) 0xcd, "expected -51 got %d\n", os2.base_ios.fill); + ok(os2.base_ios.width == (char) 0xcd, "expected -51 got %d\n", os2.base_ios.width); + ok(os2.base_ios.do_lock == -1, "expected -1 got %d\n", os2.base_ios.do_lock); + call_func1(p_ostrstream_vbase_dtor, &os2); + + /* assignment */ + os2.unknown = 0xabababab; + memset(&os2.base_ios, 0xab, sizeof(ios)); + os2.base_ios.delbuf = 0; + pos = call_func2(p_ostrstream_assign, &os2, &os1); + ok(pos == &os2, "wrong return, expected %p got %p\n", &os2, pos); + ok(os2.unknown == 0xabababab, "expected %d got %d\n", 0xabababab, os2.unknown); + ok(os2.base_ios.sb == NULL, "expected %p got %p\n", NULL, os2.base_ios.sb); + ok(os2.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, os2.base_ios.state); + ok(os2.base_ios.delbuf == 0, "expected 0 got %d\n", os2.base_ios.delbuf); + ok(os2.base_ios.tie == NULL, "expected %p got %p\n", NULL, os2.base_ios.tie); + ok(os2.base_ios.flags == 0, "expected %x got %x\n", 0, os2.base_ios.flags); + ok(os2.base_ios.precision == 6, "expected 6 got %d\n", os2.base_ios.precision); + ok(os2.base_ios.fill == ' ', "expected 32 got %d\n", os2.base_ios.fill); + ok(os2.base_ios.width == 0, "expected 0 got %d\n", os2.base_ios.width); + ok(os2.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, os2.base_ios.do_lock); +} + static void test_istream(void) { istream is1, is2, *pis; @@ -6375,6 +6661,7 @@ START_TEST(msvcirt) test_ostream(); test_ostream_print(); test_ostream_withassign(); + test_ostrstream(); test_istream(); test_istream_getint(); test_istream_getdouble(); -- 2.7.4 From matellanesivan at gmail.com Wed Oct 19 07:00:54 2016 From: matellanesivan at gmail.com (=?UTF-8?q?Iv=C3=A1n=20Matellanes?=) Date: Wed, 19 Oct 2016 14:00:54 +0200 Subject: [4/6] msvcirt/tests: Add tests of ostrstream::pcount. In-Reply-To: <1476878456-8303-1-git-send-email-matellanesivan@gmail.com> References: <1476878456-8303-1-git-send-email-matellanesivan@gmail.com> Message-ID: <1476878456-8303-4-git-send-email-matellanesivan@gmail.com> Signed-off-by: Iván Matellanes --- dlls/msvcirt/tests/msvcirt.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c index e656866..db3ee3b 100644 --- a/dlls/msvcirt/tests/msvcirt.c +++ b/dlls/msvcirt/tests/msvcirt.c @@ -336,6 +336,7 @@ static ostream* (*__thiscall p_ostrstream_ctor)(ostream*, BOOL); static void (*__thiscall p_ostrstream_dtor)(ios*); static void (*__thiscall p_ostrstream_vbase_dtor)(ostream*); static ostream* (*__thiscall p_ostrstream_assign)(ostream*, const ostream*); +static int (*__thiscall p_ostrstream_pcount)(const ostream*); /* istream */ static istream* (*__thiscall p_istream_copy_ctor)(istream*, const istream*, BOOL); @@ -608,6 +609,7 @@ static BOOL init(void) SET(p_ostrstream_dtor, "??1ostrstream@@UEAA at XZ"); SET(p_ostrstream_vbase_dtor, "??_Dostrstream@@QEAAXXZ"); SET(p_ostrstream_assign, "??4ostrstream@@QEAAAEAV0 at AEBV0@@Z"); + SET(p_ostrstream_pcount, "?pcount at ostrstream@@QEBAHXZ"); SET(p_istream_copy_ctor, "??0istream@@IEAA at AEBV0@@Z"); SET(p_istream_ctor, "??0istream@@IEAA at XZ"); @@ -794,6 +796,7 @@ static BOOL init(void) SET(p_ostrstream_dtor, "??1ostrstream@@UAE at XZ"); SET(p_ostrstream_vbase_dtor, "??_Dostrstream@@QAEXXZ"); SET(p_ostrstream_assign, "??4ostrstream@@QAEAAV0 at ABV0@@Z"); + SET(p_ostrstream_pcount, "?pcount at ostrstream@@QBEHXZ"); SET(p_istream_copy_ctor, "??0istream@@IAE at ABV0@@Z"); SET(p_istream_ctor, "??0istream@@IAE at XZ"); @@ -3996,6 +3999,7 @@ static void test_ostrstream(void) ostream os1, os2, *pos, *pos2; strstreambuf *pssb; char buffer[32]; + int ret; memset(&os1, 0xab, sizeof(ostream)); memset(&os2, 0xab, sizeof(ostream)); @@ -4253,6 +4257,28 @@ static void test_ostrstream(void) ok(os2.base_ios.fill == ' ', "expected 32 got %d\n", os2.base_ios.fill); ok(os2.base_ios.width == 0, "expected 0 got %d\n", os2.base_ios.width); ok(os2.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, os2.base_ios.do_lock); + + /* pcount */ + pos = call_func2(p_ostrstream_ctor, &os1, TRUE); + ok(pos == &os1, "wrong return, expected %p got %p\n", &os1, pos); + ret = (int) call_func1(p_ostrstream_pcount, &os1); + ok(ret == 0, "expected 0 got %d\n", ret); + pssb = (strstreambuf*) os1.base_ios.sb; + pssb->base.pptr = (char*) 5; + ret = (int) call_func1(p_ostrstream_pcount, &os1); + ok(ret == 5, "expected 5 got %d\n", ret); + pssb->base.pbase = (char*) 2; + ret = (int) call_func1(p_ostrstream_pcount, &os1); + ok(ret == 3, "expected 3 got %d\n", ret); + pssb->base.pptr = NULL; + ret = (int) call_func1(p_ostrstream_pcount, &os1); + ok(ret == 0, "expected 0 got %d\n", ret); + if (0) /* crashes on native */ + os1.base_ios.sb = NULL; + pssb->base.pptr = (char*) 1; + ret = (int) call_func1(p_ostrstream_pcount, &os1); + ok(ret == 0, "expected 0 got %d\n", ret); + call_func1(p_ostrstream_vbase_dtor, &os1); } static void test_istream(void) -- 2.7.4 From matellanesivan at gmail.com Wed Oct 19 07:00:55 2016 From: matellanesivan at gmail.com (=?UTF-8?q?Iv=C3=A1n=20Matellanes?=) Date: Wed, 19 Oct 2016 14:00:55 +0200 Subject: [5/6] msvcirt: Add a partial implementation of class istrstream. In-Reply-To: <1476878456-8303-1-git-send-email-matellanesivan@gmail.com> References: <1476878456-8303-1-git-send-email-matellanesivan@gmail.com> Message-ID: <1476878456-8303-5-git-send-email-matellanesivan@gmail.com> Signed-off-by: Iván Matellanes --- dlls/msvcirt/msvcirt.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ dlls/msvcirt/msvcirt.spec | 40 +++++++++++++++--------------- dlls/msvcrt20/msvcrt20.spec | 40 +++++++++++++++--------------- dlls/msvcrt40/msvcrt40.spec | 40 +++++++++++++++--------------- 4 files changed, 119 insertions(+), 60 deletions(-) diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index ffa7b93..a711ca9 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -191,6 +191,8 @@ extern const vtable_ptr MSVCP_ostrstream_vtable; extern const vtable_ptr MSVCP_istream_vtable; /* ??_7istream_withassign@@6B@ */ extern const vtable_ptr MSVCP_istream_withassign_vtable; +/* ??_7istrstream@@6B@ */ +extern const vtable_ptr MSVCP_istrstream_vtable; /* ??_7iostream@@6B@ */ extern const vtable_ptr MSVCP_iostream_vtable; @@ -257,6 +259,8 @@ void __asm_dummy_vtables(void) { VTABLE_ADD_FUNC(istream_vector_dtor)); __ASM_VTABLE(istream_withassign, VTABLE_ADD_FUNC(istream_vector_dtor)); + __ASM_VTABLE(istrstream, + VTABLE_ADD_FUNC(istream_vector_dtor)); __ASM_VTABLE(iostream, VTABLE_ADD_FUNC(iostream_vector_dtor)); #ifndef __GNUC__ @@ -272,6 +276,7 @@ void __asm_dummy_vtables(void) { const int ostream_vbtable[] = {0, VBTABLE_ENTRY(ostream, FIELD_OFFSET(ostream, vbtable), ios)}; /* ??_8istream@@7B@ */ /* ??_8istream_withassign@@7B@ */ +/* ??_8istrstream@@7B@ */ const int istream_vbtable[] = {0, VBTABLE_ENTRY(istream, FIELD_OFFSET(istream, vbtable), ios)}; /* ??_8iostream@@7Bistream@@@ */ const int iostream_vbtable_istream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base1), ios)}; @@ -291,6 +296,8 @@ DEFINE_RTTI_DATA2(ostrstream, sizeof(ostream), DEFINE_RTTI_DATA1(istream, sizeof(istream), &ios_rtti_base_descriptor, ".?AVistream@@") DEFINE_RTTI_DATA2(istream_withassign, sizeof(istream), &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVistream_withassign@@") +DEFINE_RTTI_DATA2(istrstream, sizeof(istream), + &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVistrstream@@") DEFINE_RTTI_DATA4(iostream, sizeof(iostream), &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AViostream@@") @@ -3091,6 +3098,8 @@ istream* __thiscall istream_copy_ctor(istream *this, const istream *copy, BOOL v /* ??1istream@@UEAA at XZ */ /* ??1istream_withassign@@UAE at XZ */ /* ??1istream_withassign@@UEAA at XZ */ +/* ??1istrstream@@UAE at XZ */ +/* ??1istrstream@@UEAA at XZ */ DEFINE_THISCALL_WRAPPER(istream_dtor, 4) void __thiscall istream_dtor(ios *base) { @@ -3128,6 +3137,8 @@ istream* __thiscall istream_assign_sb(istream *this, streambuf *sb) /* ??4istream_withassign@@QEAAAEAV0 at AEBV0@@Z */ /* ??4istream_withassign@@QAEAAVistream@@ABV1@@Z */ /* ??4istream_withassign@@QEAAAEAVistream@@AEBV1@@Z */ +/* ??4istrstream@@QAEAAV0 at ABV0@@Z */ +/* ??4istrstream@@QEAAAEAV0 at AEBV0@@Z */ DEFINE_THISCALL_WRAPPER(istream_assign, 8) istream* __thiscall istream_assign(istream *this, const istream *rhs) { @@ -3138,6 +3149,8 @@ istream* __thiscall istream_assign(istream *this, const istream *rhs) /* ??_Distream@@QEAAXXZ */ /* ??_Distream_withassign@@QAEXXZ */ /* ??_Distream_withassign@@QEAAXXZ */ +/* ??_Distrstream@@QAEXXZ */ +/* ??_Distrstream@@QEAAXXZ */ DEFINE_THISCALL_WRAPPER(istream_vbase_dtor, 4) void __thiscall istream_vbase_dtor(istream *this) { @@ -3151,6 +3164,7 @@ void __thiscall istream_vbase_dtor(istream *this) /* ??_Eistream@@UAEPAXI at Z */ /* ??_Eistream_withassign@@UAEPAXI at Z */ +/* ??_Eistrstream@@UAEPAXI at Z */ DEFINE_THISCALL_WRAPPER(istream_vector_dtor, 8) istream* __thiscall istream_vector_dtor(ios *base, unsigned int flags) { @@ -3175,6 +3189,7 @@ istream* __thiscall istream_vector_dtor(ios *base, unsigned int flags) /* ??_Gistream@@UAEPAXI at Z */ /* ??_Gistream_withassign@@UAEPAXI at Z */ +/* ??_Gistrstream@@UAEPAXI at Z */ DEFINE_THISCALL_WRAPPER(istream_scalar_dtor, 8) istream* __thiscall istream_scalar_dtor(ios *base, unsigned int flags) { @@ -4005,6 +4020,49 @@ istream* __thiscall istream_withassign_ctor(istream *this, BOOL virt_init) return this; } +/* ??0istrstream@@QAE at ABV0@@Z */ +/* ??0istrstream@@QEAA at AEBV0@@Z */ +DEFINE_THISCALL_WRAPPER(istrstream_copy_ctor, 12) +istream* __thiscall istrstream_copy_ctor(istream *this, const istream *copy, BOOL virt_init) +{ + FIXME("(%p %p %d) stub\n", this, copy, virt_init); + return this; +} + +/* ??0istrstream@@QAE at PADH@Z */ +/* ??0istrstream@@QEAA at PEADH@Z */ +DEFINE_THISCALL_WRAPPER(istrstream_buffer_ctor, 16) +istream* __thiscall istrstream_buffer_ctor(istream *this, char *buffer, int length, BOOL virt_init) +{ + FIXME("(%p %p %d %d) stub\n", this, buffer, length, virt_init); + return this; +} + +/* ??0istrstream@@QAE at PAD@Z */ +/* ??0istrstream@@QEAA at PEAD@Z */ +DEFINE_THISCALL_WRAPPER(istrstream_str_ctor, 12) +istream* __thiscall istrstream_str_ctor(istream *this, char *str, BOOL virt_init) +{ + FIXME("(%p %p %d) stub\n", this, str, virt_init); + return this; +} + +/* ?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ */ +/* ?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ */ +DEFINE_THISCALL_WRAPPER(istrstream_rdbuf, 4) +strstreambuf* __thiscall istrstream_rdbuf(const istream *this) +{ + return (strstreambuf*) istream_get_ios(this)->sb; +} + +/* ?str at istrstream@@QAEPADXZ */ +/* ?str at istrstream@@QEAAPEADXZ */ +DEFINE_THISCALL_WRAPPER(istrstream_str, 4) +char* __thiscall istrstream_str(istream *this) +{ + return strstreambuf_str(istrstream_rdbuf(this)); +} + static inline ios* iostream_to_ios(const iostream *this) { return (ios*)((char*)this + iostream_vbtable_istream[1]); @@ -4290,6 +4348,7 @@ static void init_io(void *base) init_ostrstream_rtti(base); init_istream_rtti(base); init_istream_withassign_rtti(base); + init_istrstream_rtti(base); init_iostream_rtti(base); #endif diff --git a/dlls/msvcirt/msvcirt.spec b/dlls/msvcirt/msvcirt.spec index 5b09a3d..598d42a 100644 --- a/dlls/msvcirt/msvcirt.spec +++ b/dlls/msvcirt/msvcirt.spec @@ -60,12 +60,12 @@ @ cdecl -arch=win64 ??0istream_withassign@@QEAA at PEAVstreambuf@@@Z(ptr ptr long) istream_withassign_sb_ctor @ thiscall -arch=win32 ??0istream_withassign@@QAE at XZ(ptr long) istream_withassign_ctor @ cdecl -arch=win64 ??0istream_withassign@@QEAA at XZ(ptr long) istream_withassign_ctor -@ stub -arch=win32 ??0istrstream@@QAE at ABV0@@Z # __thiscall istrstream::istrstream(class istrstream const &) -@ stub -arch=win64 ??0istrstream@@QEAA at AEBV0@@Z -@ stub -arch=win32 ??0istrstream@@QAE at PAD@Z # __thiscall istrstream::istrstream(char *) -@ stub -arch=win64 ??0istrstream@@QEAA at PEAD@Z -@ stub -arch=win32 ??0istrstream@@QAE at PADH@Z # __thiscall istrstream::istrstream(char *,int) -@ stub -arch=win64 ??0istrstream@@QEAA at PEADH@Z +@ thiscall -arch=win32 ??0istrstream@@QAE at ABV0@@Z(ptr ptr long) istrstream_copy_ctor +@ cdecl -arch=win64 ??0istrstream@@QEAA at AEBV0@@Z(ptr ptr long) istrstream_copy_ctor +@ thiscall -arch=win32 ??0istrstream@@QAE at PAD@Z(ptr ptr long) istrstream_str_ctor +@ cdecl -arch=win64 ??0istrstream@@QEAA at PEAD@Z(ptr ptr long) istrstream_str_ctor +@ thiscall -arch=win32 ??0istrstream@@QAE at PADH@Z(ptr ptr long long) istrstream_buffer_ctor +@ cdecl -arch=win64 ??0istrstream@@QEAA at PEADH@Z(ptr ptr long long) istrstream_buffer_ctor @ thiscall -arch=win32 ??0logic_error@@QAE at ABQBD@Z(ptr ptr) MSVCP_logic_error_ctor @ cdecl -arch=win64 ??0logic_error@@QEAA at AEBQEBD@Z(ptr ptr) MSVCP_logic_error_ctor @ thiscall -arch=win32 ??0logic_error@@QAE at ABV0@@Z(ptr ptr) MSVCP_logic_error_copy_ctor @@ -148,8 +148,8 @@ @ cdecl -arch=win64 ??1istream@@UEAA at XZ(ptr) istream_dtor @ thiscall -arch=win32 ??1istream_withassign@@UAE at XZ(ptr) istream_dtor @ cdecl -arch=win64 ??1istream_withassign@@UEAA at XZ(ptr) istream_dtor -@ stub -arch=win32 ??1istrstream@@UAE at XZ # virtual __thiscall istrstream::~istrstream(void) -@ stub -arch=win64 ??1istrstream@@UEAA at XZ +@ thiscall -arch=win32 ??1istrstream@@UAE at XZ(ptr) istream_dtor +@ cdecl -arch=win64 ??1istrstream@@UEAA at XZ(ptr) istream_dtor @ thiscall -arch=win32 ??1logic_error@@UAE at XZ(ptr) MSVCP_logic_error_dtor @ cdecl -arch=win64 ??1logic_error@@UEAA at XZ(ptr) MSVCP_logic_error_dtor @ stub -arch=win32 ??1ofstream@@UAE at XZ # virtual __thiscall ofstream::~ofstream(void) @@ -196,8 +196,8 @@ @ cdecl -arch=win64 ??4istream_withassign@@QEAAAEAVistream@@AEBV1@@Z(ptr ptr) istream_assign @ thiscall -arch=win32 ??4istream_withassign@@QAEAAVistream@@PAVstreambuf@@@Z(ptr ptr) istream_assign_sb @ cdecl -arch=win64 ??4istream_withassign@@QEAAAEAVistream@@PEAVstreambuf@@@Z(ptr ptr) istream_assign_sb -@ stub -arch=win32 ??4istrstream@@QAEAAV0 at ABV0@@Z # class istrstream & __thiscall istrstream::operator=(class istrstream const &) -@ stub -arch=win64 ??4istrstream@@QEAAAEAV0 at AEBV0@@Z +@ thiscall -arch=win32 ??4istrstream@@QAEAAV0 at ABV0@@Z(ptr ptr) istream_assign +@ cdecl -arch=win64 ??4istrstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) istream_assign @ thiscall -arch=win32 ??4logic_error@@QAEAAV0 at ABV0@@Z(ptr ptr) MSVCP_logic_error_assign @ cdecl -arch=win64 ??4logic_error@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) MSVCP_logic_error_assign @ stub -arch=win32 ??4ofstream@@QAEAAV0 at ABV0@@Z # class ofstream & __thiscall ofstream::operator=(class ofstream const &) @@ -310,7 +310,7 @@ @ extern ??_7iostream@@6B@ MSVCP_iostream_vtable @ extern ??_7istream@@6B@ MSVCP_istream_vtable @ extern ??_7istream_withassign@@6B@ MSVCP_istream_vtable -# @ extern ??_7istrstream@@6B@ # const istrstream::`vftable' +@ extern ??_7istrstream@@6B@ MSVCP_istrstream_vtable @ extern ??_7logic_error@@6B@ MSVCP_logic_error_vtable # @ extern ??_7ofstream@@6B@ # const ofstream::`vftable' @ extern ??_7ostream@@6B@ MSVCP_ostream_vtable @@ -328,7 +328,7 @@ @ extern ??_8iostream@@7Bostream@@@ iostream_vbtable_ostream @ extern ??_8istream@@7B@ istream_vbtable @ extern ??_8istream_withassign@@7B@ istream_vbtable -# @ extern ??_8istrstream@@7B@ # const istrstream::`vbtable' +@ extern ??_8istrstream@@7B@ istream_vbtable # @ extern ??_8ofstream@@7B@ # const ofstream::`vbtable' @ extern ??_8ostream@@7B@ ostream_vbtable @ extern ??_8ostream_withassign@@7B@ ostream_vbtable @@ -347,8 +347,8 @@ @ cdecl -arch=win64 ??_Distream@@QEAAXXZ(ptr) istream_vbase_dtor @ thiscall -arch=win32 ??_Distream_withassign@@QAEXXZ(ptr) istream_vbase_dtor @ cdecl -arch=win64 ??_Distream_withassign@@QEAAXXZ(ptr) istream_vbase_dtor -@ stub -arch=win32 ??_Distrstream@@QAEXXZ # void __thiscall istrstream::`vbase destructor'(void) -@ stub -arch=win64 ??_Distrstream@@QEAAXXZ +@ thiscall -arch=win32 ??_Distrstream@@QAEXXZ(ptr) istream_vbase_dtor +@ cdecl -arch=win64 ??_Distrstream@@QEAAXXZ(ptr) istream_vbase_dtor @ stub -arch=win32 ??_Dofstream@@QAEXXZ # void __thiscall ofstream::`vbase destructor'(void) @ stub -arch=win64 ??_Dofstream@@QEAAXXZ @ thiscall -arch=win32 ??_Dostream@@QAEXXZ(ptr) ostream_vbase_dtor @@ -369,7 +369,7 @@ @ thiscall -arch=win32 ??_Eiostream@@UAEPAXI at Z(ptr long) iostream_vector_dtor @ thiscall -arch=win32 ??_Eistream@@UAEPAXI at Z(ptr long) istream_vector_dtor @ thiscall -arch=win32 ??_Eistream_withassign@@UAEPAXI at Z(ptr long) istream_vector_dtor -@ stub -arch=win32 ??_Eistrstream@@UAEPAXI at Z # virtual void * __thiscall istrstream::`vector deleting destructor'(unsigned int) +@ thiscall -arch=win32 ??_Eistrstream@@UAEPAXI at Z(ptr long) istream_vector_dtor @ thiscall -arch=win32 ??_Elogic_error@@UAEPAXI at Z(ptr long) MSVCP_logic_error_vector_dtor @ stub -arch=win32 ??_Eofstream@@UAEPAXI at Z # virtual void * __thiscall ofstream::`vector deleting destructor'(unsigned int) @ thiscall -arch=win32 ??_Eostream@@UAEPAXI at Z(ptr long) ostream_vector_dtor @@ -388,7 +388,7 @@ @ thiscall -arch=win32 ??_Giostream@@UAEPAXI at Z(ptr long) iostream_scalar_dtor @ thiscall -arch=win32 ??_Gistream@@UAEPAXI at Z(ptr long) istream_scalar_dtor @ thiscall -arch=win32 ??_Gistream_withassign@@UAEPAXI at Z(ptr long) istream_scalar_dtor -@ stub -arch=win32 ??_Gistrstream@@UAEPAXI at Z # virtual void * __thiscall istrstream::`scalar deleting destructor'(unsigned int) +@ thiscall -arch=win32 ??_Gistrstream@@UAEPAXI at Z(ptr long) istream_scalar_dtor @ thiscall -arch=win32 ??_Glogic_error@@UAEPAXI at Z(ptr long) MSVCP_logic_error_scalar_dtor @ stub -arch=win32 ??_Gofstream@@UAEPAXI at Z # virtual void * __thiscall ofstream::`scalar deleting destructor'(unsigned int) @ thiscall -arch=win32 ??_Gostream@@UAEPAXI at Z(ptr long) ostream_scalar_dtor @@ -619,8 +619,8 @@ @ stub -arch=win64 ?rdbuf at ifstream@@QEBAPEAVfilebuf@@XZ @ thiscall -arch=win32 ?rdbuf at ios@@QBEPAVstreambuf@@XZ(ptr) ios_rdbuf @ cdecl -arch=win64 ?rdbuf at ios@@QEBAPEAVstreambuf@@XZ(ptr) ios_rdbuf -@ stub -arch=win32 ?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ # class strstreambuf * __thiscall istrstream::rdbuf(void)const -@ stub -arch=win64 ?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ +@ thiscall -arch=win32 ?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ(ptr) istrstream_rdbuf +@ cdecl -arch=win64 ?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) istrstream_rdbuf @ stub -arch=win32 ?rdbuf at ofstream@@QBEPAVfilebuf@@XZ # class filebuf * __thiscall ofstream::rdbuf(void)const @ stub -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ @ thiscall -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ(ptr) ostrstream_rdbuf @@ -712,8 +712,8 @@ @ cdecl -arch=win64 ?stdiofile at stdiobuf@@QEAAPEAU_iobuf@@XZ(ptr) stdiobuf_stdiofile @ thiscall -arch=win32 ?stossc at streambuf@@QAEXXZ(ptr) streambuf_stossc @ cdecl -arch=win64 ?stossc at streambuf@@QEAAXXZ(ptr) streambuf_stossc -@ stub -arch=win32 ?str at istrstream@@QAEPADXZ # char * __thiscall istrstream::str(void) -@ stub -arch=win64 ?str at istrstream@@QEAAPEADXZ +@ thiscall -arch=win32 ?str at istrstream@@QAEPADXZ(ptr) istrstream_str +@ cdecl -arch=win64 ?str at istrstream@@QEAAPEADXZ(ptr) istrstream_str @ thiscall -arch=win32 ?str at ostrstream@@QAEPADXZ(ptr) ostrstream_str @ cdecl -arch=win64 ?str at ostrstream@@QEAAPEADXZ(ptr) ostrstream_str @ stub -arch=win32 ?str at strstream@@QAEPADXZ # char * __thiscall strstream::str(void) diff --git a/dlls/msvcrt20/msvcrt20.spec b/dlls/msvcrt20/msvcrt20.spec index 237c106..584a85e 100644 --- a/dlls/msvcrt20/msvcrt20.spec +++ b/dlls/msvcrt20/msvcrt20.spec @@ -54,12 +54,12 @@ @ cdecl -arch=win64 ??0istream_withassign@@QEAA at PEAVstreambuf@@@Z(ptr ptr long) msvcirt.??0istream_withassign@@QEAA at PEAVstreambuf@@@Z @ thiscall -arch=win32 ??0istream_withassign@@QAE at XZ(ptr long) msvcirt.??0istream_withassign@@QAE at XZ @ cdecl -arch=win64 ??0istream_withassign@@QEAA at XZ(ptr long) msvcirt.??0istream_withassign@@QEAA at XZ -@ stub -arch=win32 ??0istrstream@@QAE at ABV0@@Z -@ stub -arch=win64 ??0istrstream@@QEAA at AEBV0@@Z -@ stub -arch=win32 ??0istrstream@@QAE at PAD@Z -@ stub -arch=win64 ??0istrstream@@QEAA at PEAD@Z -@ stub -arch=win32 ??0istrstream@@QAE at PADH@Z -@ stub -arch=win64 ??0istrstream@@QEAA at PEADH@Z +@ thiscall -arch=win32 ??0istrstream@@QAE at ABV0@@Z(ptr ptr long) msvcirt.??0istrstream@@QAE at ABV0@@Z +@ cdecl -arch=win64 ??0istrstream@@QEAA at AEBV0@@Z(ptr ptr long) msvcirt.??0istrstream@@QEAA at AEBV0@@Z +@ thiscall -arch=win32 ??0istrstream@@QAE at PAD@Z(ptr ptr long) msvcirt.??0istrstream@@QAE at PAD@Z +@ cdecl -arch=win64 ??0istrstream@@QEAA at PEAD@Z(ptr ptr long) msvcirt.??0istrstream@@QEAA at PEAD@Z +@ thiscall -arch=win32 ??0istrstream@@QAE at PADH@Z(ptr ptr long long) msvcirt.??0istrstream@@QAE at PADH@Z +@ cdecl -arch=win64 ??0istrstream@@QEAA at PEADH@Z(ptr ptr long long) msvcirt.??0istrstream@@QEAA at PEADH@Z @ stub -arch=win32 ??0ofstream@@QAE at ABV0@@Z @ stub -arch=win64 ??0ofstream@@QEAA at AEBV0@@Z @ stub -arch=win32 ??0ofstream@@QAE at H@Z @@ -134,8 +134,8 @@ @ cdecl -arch=win64 ??1istream@@UEAA at XZ(ptr) msvcirt.??1istream@@UEAA at XZ @ thiscall -arch=win32 ??1istream_withassign@@UAE at XZ(ptr) msvcirt.??1istream_withassign@@UAE at XZ @ cdecl -arch=win64 ??1istream_withassign@@UEAA at XZ(ptr) msvcirt.??1istream_withassign@@UEAA at XZ -@ stub -arch=win32 ??1istrstream@@UAE at XZ -@ stub -arch=win64 ??1istrstream@@UEAA at XZ +@ thiscall -arch=win32 ??1istrstream@@UAE at XZ(ptr) msvcirt.??1istrstream@@UAE at XZ +@ cdecl -arch=win64 ??1istrstream@@UEAA at XZ(ptr) msvcirt.??1istrstream@@UEAA at XZ @ stub -arch=win32 ??1ofstream@@UAE at XZ @ stub -arch=win64 ??1ofstream@@UEAA at XZ @ thiscall -arch=win32 ??1ostream@@UAE at XZ(ptr) msvcirt.??1ostream@@UAE at XZ @@ -182,8 +182,8 @@ @ cdecl -arch=win64 ??4istream_withassign@@QEAAAEAVistream@@AEBV1@@Z(ptr ptr) msvcirt.??4istream_withassign@@QEAAAEAVistream@@AEBV1@@Z @ thiscall -arch=win32 ??4istream_withassign@@QAEAAVistream@@PAVstreambuf@@@Z(ptr ptr) msvcirt.??4istream_withassign@@QAEAAVistream@@PAVstreambuf@@@Z @ cdecl -arch=win64 ??4istream_withassign@@QEAAAEAVistream@@PEAVstreambuf@@@Z(ptr ptr) msvcirt.??4istream_withassign@@QEAAAEAVistream@@PEAVstreambuf@@@Z -@ stub -arch=win32 ??4istrstream@@QAEAAV0 at ABV0@@Z -@ stub -arch=win64 ??4istrstream@@QEAAAEAV0 at AEBV0@@Z +@ thiscall -arch=win32 ??4istrstream@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4istrstream@@QAEAAV0 at ABV0@@Z +@ cdecl -arch=win64 ??4istrstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4istrstream@@QEAAAEAV0 at AEBV0@@Z @ stub -arch=win32 ??4ofstream@@QAEAAV0 at ABV0@@Z @ stub -arch=win64 ??4ofstream@@QEAAAEAV0 at AEBV0@@Z @ thiscall -arch=win32 ??4ostream@@IAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4ostream@@IAEAAV0 at ABV0@@Z @@ -293,7 +293,7 @@ @ extern ??_7iostream@@6B@ msvcirt.??_7iostream@@6B@ @ extern ??_7istream@@6B@ msvcirt.??_7istream@@6B@ @ extern ??_7istream_withassign@@6B@ msvcirt.??_7istream_withassign@@6B@ -# @ extern ??_7istrstream@@6B@ +@ extern ??_7istrstream@@6B@ msvcirt.??_7istrstream@@6B@ # @ extern ??_7ofstream@@6B@ @ extern ??_7ostream@@6B@ msvcirt.??_7ostream@@6B@ @ extern ??_7ostream_withassign@@6B@ msvcirt.??_7ostream_withassign@@6B@ @@ -310,7 +310,7 @@ @ extern ??_8iostream@@7Bostream@@@ msvcirt.??_8iostream@@7Bostream@@@ @ extern ??_8istream@@7B@ msvcirt.??_8istream@@7B@ @ extern ??_8istream_withassign@@7B@ msvcirt.??_8istream_withassign@@7B@ -# @ extern ??_8istrstream@@7B@ +@ extern ??_8istrstream@@7B@ msvcirt.??_8istrstream@@7B@ # @ extern ??_8ofstream@@7B@ @ extern ??_8ostream@@7B@ msvcirt.??_8ostream@@7B@ @ extern ??_8ostream_withassign@@7B@ msvcirt.??_8ostream_withassign@@7B@ @@ -329,8 +329,8 @@ @ cdecl -arch=win64 ??_Distream@@QEAAXXZ(ptr) msvcirt.??_Distream@@QEAAXXZ @ thiscall -arch=win32 ??_Distream_withassign@@QAEXXZ(ptr) msvcirt.??_Distream_withassign@@QAEXXZ @ cdecl -arch=win64 ??_Distream_withassign@@QEAAXXZ(ptr) msvcirt.??_Distream_withassign@@QEAAXXZ -@ stub -arch=win32 ??_Distrstream@@QAEXXZ -@ stub -arch=win64 ??_Distrstream@@QEAAXXZ +@ thiscall -arch=win32 ??_Distrstream@@QAEXXZ(ptr) msvcirt.??_Distrstream@@QAEXXZ +@ cdecl -arch=win64 ??_Distrstream@@QEAAXXZ(ptr) msvcirt.??_Distrstream@@QEAAXXZ @ stub -arch=win32 ??_Dofstream@@QAEXXZ @ stub -arch=win64 ??_Dofstream@@QEAAXXZ @ thiscall -arch=win32 ??_Dostream@@QAEXXZ(ptr) msvcirt.??_Dostream@@QAEXXZ @@ -351,7 +351,7 @@ @ thiscall -arch=win32 ??_Eiostream@@UAEPAXI at Z(ptr long) msvcirt.??_Eiostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Eistream@@UAEPAXI at Z(ptr long) msvcirt.??_Eistream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Eistream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Eistream_withassign@@UAEPAXI at Z -@ stub -arch=win32 ??_Eistrstream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Eistrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Eistrstream@@UAEPAXI at Z @ stub -arch=win32 ??_Eofstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Eostream@@UAEPAXI at Z(ptr long) msvcirt.??_Eostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Eostream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Eostream_withassign@@UAEPAXI at Z @@ -369,7 +369,7 @@ @ thiscall -arch=win32 ??_Giostream@@UAEPAXI at Z(ptr long) msvcirt.??_Giostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gistream@@UAEPAXI at Z(ptr long) msvcirt.??_Gistream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gistream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Gistream_withassign@@UAEPAXI at Z -@ stub -arch=win32 ??_Gistrstream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Gistrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gistrstream@@UAEPAXI at Z @ stub -arch=win32 ??_Gofstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gostream@@UAEPAXI at Z(ptr long) msvcirt.??_Gostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gostream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Gostream_withassign@@UAEPAXI at Z @@ -605,8 +605,8 @@ @ stub -arch=win64 ?rdbuf at ifstream@@QEBAPEAVfilebuf@@XZ @ thiscall -arch=win32 ?rdbuf at ios@@QBEPAVstreambuf@@XZ(ptr) msvcirt.?rdbuf at ios@@QBEPAVstreambuf@@XZ @ cdecl -arch=win64 ?rdbuf at ios@@QEBAPEAVstreambuf@@XZ(ptr) msvcirt.?rdbuf at ios@@QEBAPEAVstreambuf@@XZ -@ stub -arch=win32 ?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ -@ stub -arch=win64 ?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ +@ thiscall -arch=win32 ?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ +@ cdecl -arch=win64 ?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ @ stub -arch=win32 ?rdbuf at ofstream@@QBEPAVfilebuf@@XZ @ stub -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ @ thiscall -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ @@ -700,8 +700,8 @@ @ cdecl -arch=win64 ?stdiofile at stdiobuf@@QEAAPEAU_iobuf@@XZ(ptr) msvcirt.?stdiofile at stdiobuf@@QEAAPEAU_iobuf@@XZ @ thiscall -arch=win32 ?stossc at streambuf@@QAEXXZ(ptr) msvcirt.?stossc at streambuf@@QAEXXZ @ cdecl -arch=win64 ?stossc at streambuf@@QEAAXXZ(ptr) msvcirt.?stossc at streambuf@@QEAAXXZ -@ stub -arch=win32 ?str at istrstream@@QAEPADXZ -@ stub -arch=win64 ?str at istrstream@@QEAAPEADXZ +@ thiscall -arch=win32 ?str at istrstream@@QAEPADXZ(ptr) msvcirt.?str at istrstream@@QAEPADXZ +@ cdecl -arch=win64 ?str at istrstream@@QEAAPEADXZ(ptr) msvcirt.?str at istrstream@@QEAAPEADXZ @ thiscall -arch=win32 ?str at ostrstream@@QAEPADXZ(ptr) msvcirt.?str at ostrstream@@QAEPADXZ @ cdecl -arch=win64 ?str at ostrstream@@QEAAPEADXZ(ptr) msvcirt.?str at ostrstream@@QEAAPEADXZ @ stub -arch=win32 ?str at strstream@@QAEPADXZ diff --git a/dlls/msvcrt40/msvcrt40.spec b/dlls/msvcrt40/msvcrt40.spec index 94293be..7c83691 100644 --- a/dlls/msvcrt40/msvcrt40.spec +++ b/dlls/msvcrt40/msvcrt40.spec @@ -72,12 +72,12 @@ @ cdecl -arch=win64 ??0istream_withassign@@QEAA at PEAVstreambuf@@@Z(ptr ptr long) msvcirt.??0istream_withassign@@QEAA at PEAVstreambuf@@@Z @ thiscall -arch=win32 ??0istream_withassign@@QAE at XZ(ptr long) msvcirt.??0istream_withassign@@QAE at XZ @ cdecl -arch=win64 ??0istream_withassign@@QEAA at XZ(ptr long) msvcirt.??0istream_withassign@@QEAA at XZ -@ stub -arch=win32 ??0istrstream@@QAE at ABV0@@Z -@ stub -arch=win64 ??0istrstream@@QEAA at AEBV0@@Z -@ stub -arch=win32 ??0istrstream@@QAE at PAD@Z -@ stub -arch=win64 ??0istrstream@@QEAA at PEAD@Z -@ stub -arch=win32 ??0istrstream@@QAE at PADH@Z -@ stub -arch=win64 ??0istrstream@@QEAA at PEADH@Z +@ thiscall -arch=win32 ??0istrstream@@QAE at ABV0@@Z(ptr ptr long) msvcirt.??0istrstream@@QAE at ABV0@@Z +@ cdecl -arch=win64 ??0istrstream@@QEAA at AEBV0@@Z(ptr ptr long) msvcirt.??0istrstream@@QEAA at AEBV0@@Z +@ thiscall -arch=win32 ??0istrstream@@QAE at PAD@Z(ptr ptr long) msvcirt.??0istrstream@@QAE at PAD@Z +@ cdecl -arch=win64 ??0istrstream@@QEAA at PEAD@Z(ptr ptr long) msvcirt.??0istrstream@@QEAA at PEAD@Z +@ thiscall -arch=win32 ??0istrstream@@QAE at PADH@Z(ptr ptr long long) msvcirt.??0istrstream@@QAE at PADH@Z +@ cdecl -arch=win64 ??0istrstream@@QEAA at PEADH@Z(ptr ptr long long) msvcirt.??0istrstream@@QEAA at PEADH@Z @ thiscall -arch=win32 ??0logic_error@@QAE at ABQBD@Z(ptr ptr) msvcirt.??0logic_error@@QAE at ABQBD@Z @ cdecl -arch=win64 ??0logic_error@@QEAA at AEBQEBD@Z(ptr ptr) msvcirt.??0logic_error@@QEAA at AEBQEBD@Z @ thiscall -arch=win32 ??0logic_error@@QAE at ABV0@@Z(ptr ptr) msvcirt.??0logic_error@@QAE at ABV0@@Z @@ -164,8 +164,8 @@ @ cdecl -arch=win64 ??1istream@@UEAA at XZ(ptr) msvcirt.??1istream@@UEAA at XZ @ thiscall -arch=win32 ??1istream_withassign@@UAE at XZ(ptr) msvcirt.??1istream_withassign@@UAE at XZ @ cdecl -arch=win64 ??1istream_withassign@@UEAA at XZ(ptr) msvcirt.??1istream_withassign@@UEAA at XZ -@ stub -arch=win32 ??1istrstream@@UAE at XZ -@ stub -arch=win64 ??1istrstream@@UEAA at XZ +@ thiscall -arch=win32 ??1istrstream@@UAE at XZ(ptr) msvcirt.??1istrstream@@UAE at XZ +@ cdecl -arch=win64 ??1istrstream@@UEAA at XZ(ptr) msvcirt.??1istrstream@@UEAA at XZ @ thiscall -arch=win32 ??1logic_error@@UAE at XZ(ptr) msvcirt.??1logic_error@@UAE at XZ @ cdecl -arch=win64 ??1logic_error@@UEAA at XZ(ptr) msvcirt.??1logic_error@@UEAA at XZ @ stub -arch=win32 ??1ofstream@@UAE at XZ @@ -224,8 +224,8 @@ @ cdecl -arch=win64 ??4istream_withassign@@QEAAAEAVistream@@AEBV1@@Z(ptr ptr) msvcirt.??4istream_withassign@@QEAAAEAVistream@@AEBV1@@Z @ thiscall -arch=win32 ??4istream_withassign@@QAEAAVistream@@PAVstreambuf@@@Z(ptr ptr) msvcirt.??4istream_withassign@@QAEAAVistream@@PAVstreambuf@@@Z @ cdecl -arch=win64 ??4istream_withassign@@QEAAAEAVistream@@PEAVstreambuf@@@Z(ptr ptr) msvcirt.??4istream_withassign@@QEAAAEAVistream@@PEAVstreambuf@@@Z -@ stub -arch=win32 ??4istrstream@@QAEAAV0 at ABV0@@Z -@ stub -arch=win64 ??4istrstream@@QEAAAEAV0 at AEBV0@@Z +@ thiscall -arch=win32 ??4istrstream@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4istrstream@@QAEAAV0 at ABV0@@Z +@ cdecl -arch=win64 ??4istrstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4istrstream@@QEAAAEAV0 at AEBV0@@Z @ thiscall -arch=win32 ??4logic_error@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4logic_error@@QAEAAV0 at ABV0@@Z @ cdecl -arch=win64 ??4logic_error@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4logic_error@@QEAAAEAV0 at AEBV0@@Z @ stub -arch=win32 ??4ofstream@@QAEAAV0 at ABV0@@Z @@ -345,7 +345,7 @@ @ extern ??_7iostream@@6B@ msvcirt.??_7iostream@@6B@ @ extern ??_7istream@@6B@ msvcirt.??_7istream@@6B@ @ extern ??_7istream_withassign@@6B@ msvcirt.??_7istream_withassign@@6B@ -# @ extern ??_7istrstream@@6B@ +@ extern ??_7istrstream@@6B@ msvcirt.??_7istrstream@@6B@ @ extern ??_7logic_error@@6B@ msvcirt.??_7logic_error@@6B@ # @ extern ??_7ofstream@@6B@ @ extern ??_7ostream@@6B@ msvcirt.??_7ostream@@6B@ @@ -363,7 +363,7 @@ @ extern ??_8iostream@@7Bostream@@@ msvcirt.??_8iostream@@7Bostream@@@ @ extern ??_8istream@@7B@ msvcirt.??_8istream@@7B@ @ extern ??_8istream_withassign@@7B@ msvcirt.??_8istream_withassign@@7B@ -# @ extern ??_8istrstream@@7B@ +@ extern ??_8istrstream@@7B@ msvcirt.??_8istrstream@@7B@ # @ extern ??_8ofstream@@7B@ @ extern ??_8ostream@@7B@ msvcirt.??_8ostream@@7B@ @ extern ??_8ostream_withassign@@7B@ msvcirt.??_8ostream_withassign@@7B@ @@ -382,8 +382,8 @@ @ cdecl -arch=win64 ??_Distream@@QEAAXXZ(ptr) msvcirt.??_Distream@@QEAAXXZ @ thiscall -arch=win32 ??_Distream_withassign@@QAEXXZ(ptr) msvcirt.??_Distream_withassign@@QAEXXZ @ cdecl -arch=win64 ??_Distream_withassign@@QEAAXXZ(ptr) msvcirt.??_Distream_withassign@@QEAAXXZ -@ stub -arch=win32 ??_Distrstream@@QAEXXZ -@ stub -arch=win64 ??_Distrstream@@QEAAXXZ +@ thiscall -arch=win32 ??_Distrstream@@QAEXXZ(ptr) msvcirt.??_Distrstream@@QAEXXZ +@ cdecl -arch=win64 ??_Distrstream@@QEAAXXZ(ptr) msvcirt.??_Distrstream@@QEAAXXZ @ stub -arch=win32 ??_Dofstream@@QAEXXZ @ stub -arch=win64 ??_Dofstream@@QEAAXXZ @ thiscall -arch=win32 ??_Dostream@@QAEXXZ(ptr) msvcirt.??_Dostream@@QAEXXZ @@ -408,7 +408,7 @@ @ thiscall -arch=win32 ??_Eiostream@@UAEPAXI at Z(ptr long) msvcirt.??_Eiostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Eistream@@UAEPAXI at Z(ptr long) msvcirt.??_Eistream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Eistream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Eistream_withassign@@UAEPAXI at Z -@ stub -arch=win32 ??_Eistrstream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Eistrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Eistrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Elogic_error@@UAEPAXI at Z(ptr long) msvcirt.??_Elogic_error@@UAEPAXI at Z @ stub -arch=win32 ??_Eofstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Eostream@@UAEPAXI at Z(ptr long) msvcirt.??_Eostream@@UAEPAXI at Z @@ -431,7 +431,7 @@ @ thiscall -arch=win32 ??_Giostream@@UAEPAXI at Z(ptr long) msvcirt.??_Giostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gistream@@UAEPAXI at Z(ptr long) msvcirt.??_Gistream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gistream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Gistream_withassign@@UAEPAXI at Z -@ stub -arch=win32 ??_Gistrstream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Gistrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gistrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Glogic_error@@UAEPAXI at Z(ptr long) msvcirt.??_Glogic_error@@UAEPAXI at Z @ stub -arch=win32 ??_Gofstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gostream@@UAEPAXI at Z(ptr long) msvcirt.??_Gostream@@UAEPAXI at Z @@ -676,8 +676,8 @@ @ stub -arch=win64 ?rdbuf at ifstream@@QEBAPEAVfilebuf@@XZ @ thiscall -arch=win32 ?rdbuf at ios@@QBEPAVstreambuf@@XZ(ptr) msvcirt.?rdbuf at ios@@QBEPAVstreambuf@@XZ @ cdecl -arch=win64 ?rdbuf at ios@@QEBAPEAVstreambuf@@XZ(ptr) msvcirt.?rdbuf at ios@@QEBAPEAVstreambuf@@XZ -@ stub -arch=win32 ?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ -@ stub -arch=win64 ?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ +@ thiscall -arch=win32 ?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ +@ cdecl -arch=win64 ?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ @ stub -arch=win32 ?rdbuf at ofstream@@QBEPAVfilebuf@@XZ @ stub -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ @ thiscall -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ @@ -772,8 +772,8 @@ @ cdecl -arch=win64 ?stdiofile at stdiobuf@@QEAAPEAU_iobuf@@XZ(ptr) msvcirt.?stdiofile at stdiobuf@@QEAAPEAU_iobuf@@XZ @ thiscall -arch=win32 ?stossc at streambuf@@QAEXXZ(ptr) msvcirt.?stossc at streambuf@@QAEXXZ @ cdecl -arch=win64 ?stossc at streambuf@@QEAAXXZ(ptr) msvcirt.?stossc at streambuf@@QEAAXXZ -@ stub -arch=win32 ?str at istrstream@@QAEPADXZ -@ stub -arch=win64 ?str at istrstream@@QEAAPEADXZ +@ thiscall -arch=win32 ?str at istrstream@@QAEPADXZ(ptr) msvcirt.?str at istrstream@@QAEPADXZ +@ cdecl -arch=win64 ?str at istrstream@@QEAAPEADXZ(ptr) msvcirt.?str at istrstream@@QEAAPEADXZ @ thiscall -arch=win32 ?str at ostrstream@@QAEPADXZ(ptr) msvcirt.?str at ostrstream@@QAEPADXZ @ cdecl -arch=win64 ?str at ostrstream@@QEAAPEADXZ(ptr) msvcirt.?str at ostrstream@@QEAAPEADXZ @ stub -arch=win32 ?str at strstream@@QAEPADXZ -- 2.7.4 From matellanesivan at gmail.com Wed Oct 19 07:00:56 2016 From: matellanesivan at gmail.com (=?UTF-8?q?Iv=C3=A1n=20Matellanes?=) Date: Wed, 19 Oct 2016 14:00:56 +0200 Subject: [6/6] msvcirt: Implement istrstream constructors In-Reply-To: <1476878456-8303-1-git-send-email-matellanesivan@gmail.com> References: <1476878456-8303-1-git-send-email-matellanesivan@gmail.com> Message-ID: <1476878456-8303-6-git-send-email-matellanesivan@gmail.com> Signed-off-by: Iván Matellanes --- dlls/msvcirt/msvcirt.c | 21 +++- dlls/msvcirt/tests/msvcirt.c | 260 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 277 insertions(+), 4 deletions(-) diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index a711ca9..c210862 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -4025,7 +4025,9 @@ istream* __thiscall istream_withassign_ctor(istream *this, BOOL virt_init) DEFINE_THISCALL_WRAPPER(istrstream_copy_ctor, 12) istream* __thiscall istrstream_copy_ctor(istream *this, const istream *copy, BOOL virt_init) { - FIXME("(%p %p %d) stub\n", this, copy, virt_init); + TRACE("(%p %p %d)\n", this, copy, virt_init); + istream_withassign_copy_ctor(this, copy, virt_init); + istream_get_ios(this)->vtable = &MSVCP_istrstream_vtable; return this; } @@ -4034,7 +4036,19 @@ istream* __thiscall istrstream_copy_ctor(istream *this, const istream *copy, BOO DEFINE_THISCALL_WRAPPER(istrstream_buffer_ctor, 16) istream* __thiscall istrstream_buffer_ctor(istream *this, char *buffer, int length, BOOL virt_init) { - FIXME("(%p %p %d %d) stub\n", this, buffer, length, virt_init); + ios *base; + strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf)); + + TRACE("(%p %p %d %d)\n", this, buffer, length, virt_init); + + if (ssb) { + strstreambuf_buffer_ctor(ssb, buffer, length, NULL); + istream_sb_ctor(this, &ssb->base, virt_init); + } else + istream_ctor(this, virt_init); + base = istream_get_ios(this); + base->vtable = &MSVCP_istrstream_vtable; + base->delbuf = 1; return this; } @@ -4043,8 +4057,7 @@ istream* __thiscall istrstream_buffer_ctor(istream *this, char *buffer, int leng DEFINE_THISCALL_WRAPPER(istrstream_str_ctor, 12) istream* __thiscall istrstream_str_ctor(istream *this, char *str, BOOL virt_init) { - FIXME("(%p %p %d) stub\n", this, str, virt_init); - return this; + return istrstream_buffer_ctor(this, str, 0, virt_init); } /* ?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ */ diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c index db3ee3b..ed87a23 100644 --- a/dlls/msvcirt/tests/msvcirt.c +++ b/dlls/msvcirt/tests/msvcirt.c @@ -387,6 +387,14 @@ static istream* (*__thiscall p_istream_withassign_assign_sb)(istream*, streambuf static istream* (*__thiscall p_istream_withassign_assign_is)(istream*, const istream*); static istream* (*__thiscall p_istream_withassign_assign)(istream*, const istream*); +/* istrstream */ +static istream* (*__thiscall p_istrstream_copy_ctor)(istream*, const istream*, BOOL); +static istream* (*__thiscall p_istrstream_str_ctor)(istream*, char*, BOOL); +static istream* (*__thiscall p_istrstream_buffer_ctor)(istream*, char*, int, BOOL); +static void (*__thiscall p_istrstream_dtor)(ios*); +static void (*__thiscall p_istrstream_vbase_dtor)(istream*); +static istream* (*__thiscall p_istrstream_assign)(istream*, const istream*); + /* iostream */ static iostream* (*__thiscall p_iostream_copy_ctor)(iostream*, const iostream*, BOOL); static iostream* (*__thiscall p_iostream_sb_ctor)(iostream*, streambuf*, BOOL); @@ -658,6 +666,13 @@ static BOOL init(void) SET(p_istream_withassign_assign_is, "??4istream_withassign@@QEAAAEAVistream@@AEBV1@@Z"); SET(p_istream_withassign_assign, "??4istream_withassign@@QEAAAEAV0 at AEBV0@@Z"); + SET(p_istrstream_copy_ctor, "??0istrstream@@QEAA at AEBV0@@Z"); + SET(p_istrstream_str_ctor, "??0istrstream@@QEAA at PEAD@Z"); + SET(p_istrstream_buffer_ctor, "??0istrstream@@QEAA at PEADH@Z"); + SET(p_istrstream_dtor, "??1istrstream@@UEAA at XZ"); + SET(p_istrstream_vbase_dtor, "??_Distrstream@@QEAAXXZ"); + SET(p_istrstream_assign, "??4istrstream@@QEAAAEAV0 at AEBV0@@Z"); + SET(p_iostream_copy_ctor, "??0iostream@@IEAA at AEBV0@@Z"); SET(p_iostream_sb_ctor, "??0iostream@@QEAA at PEAVstreambuf@@@Z"); SET(p_iostream_ctor, "??0iostream@@IEAA at XZ"); @@ -845,6 +860,13 @@ static BOOL init(void) SET(p_istream_withassign_assign_is, "??4istream_withassign@@QAEAAVistream@@ABV1@@Z"); SET(p_istream_withassign_assign, "??4istream_withassign@@QAEAAV0 at ABV0@@Z"); + SET(p_istrstream_copy_ctor, "??0istrstream@@QAE at ABV0@@Z"); + SET(p_istrstream_str_ctor, "??0istrstream@@QAE at PAD@Z"); + SET(p_istrstream_buffer_ctor, "??0istrstream@@QAE at PADH@Z"); + SET(p_istrstream_dtor, "??1istrstream@@UAE at XZ"); + SET(p_istrstream_vbase_dtor, "??_Distrstream@@QAEXXZ"); + SET(p_istrstream_assign, "??4istrstream@@QAEAAV0 at ABV0@@Z"); + SET(p_iostream_copy_ctor, "??0iostream@@IAE at ABV0@@Z"); SET(p_iostream_sb_ctor, "??0iostream@@QAE at PAVstreambuf@@@Z"); SET(p_iostream_ctor, "??0iostream@@IAE at XZ"); @@ -6169,6 +6191,243 @@ static void test_istream_withassign(void) ok(isa2.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, isa2.base_ios.do_lock); } +static void test_istrstream(void) +{ + istream is1, is2, *pis; + ostream *pos; + strstreambuf *pssb; + char buffer[32]; + + memset(&is1, 0xab, sizeof(istream)); + memset(&is2, 0xab, sizeof(istream)); + + /* constructors/destructors */ + pis = call_func4(p_istrstream_buffer_ctor, &is1, buffer, 32, TRUE); + pssb = (strstreambuf*) is1.base_ios.sb; + ok(pis == &is1, "wrong return, expected %p got %p\n", &is1, pis); + ok(is1.extract_delim == 0, "expected 0 got %d\n", is1.extract_delim); + ok(is1.count == 0, "expected 0 got %d\n", is1.count); + ok(is1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, is1.base_ios.sb); + ok(is1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, is1.base_ios.state); + ok(is1.base_ios.delbuf == 1, "expected 1 got %d\n", is1.base_ios.delbuf); + ok(is1.base_ios.tie == NULL, "expected %p got %p\n", NULL, is1.base_ios.tie); + ok(is1.base_ios.flags == FLAGS_skipws, "expected %x got %x\n", FLAGS_skipws, is1.base_ios.flags); + ok(is1.base_ios.precision == 6, "expected 6 got %d\n", is1.base_ios.precision); + ok(is1.base_ios.fill == ' ', "expected 32 got %d\n", is1.base_ios.fill); + ok(is1.base_ios.width == 0, "expected 0 got %d\n", is1.base_ios.width); + ok(is1.base_ios.do_lock == -1, "expected -1 got %d\n", is1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); + ok(pssb->base.ebuf == buffer + 32, "wrong buffer end, expected %p got %p\n", buffer + 32, pssb->base.ebuf); + ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); + ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); + ok(pssb->base.egptr == buffer + 32, "wrong get end, expected %p got %p\n", buffer + 32, pssb->base.egptr); + ok(pssb->base.pbase == NULL, "wrong put base, expected %p got %p\n", NULL, pssb->base.pbase); + ok(pssb->base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, pssb->base.pptr); + ok(pssb->base.epptr == NULL, "wrong put end, expected %p got %p\n", NULL, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_istrstream_vbase_dtor, &is1); + ok(is1.base_ios.sb == NULL, "expected %p got %p\n", NULL, is1.base_ios.sb); + ok(is1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, is1.base_ios.state); + memset(&is1, 0xab, sizeof(istream)); + pis = call_func4(p_istrstream_buffer_ctor, &is1, NULL, -1, TRUE); + pssb = (strstreambuf*) is1.base_ios.sb; + ok(pis == &is1, "wrong return, expected %p got %p\n", &is1, pis); + ok(is1.extract_delim == 0, "expected 0 got %d\n", is1.extract_delim); + ok(is1.count == 0, "expected 0 got %d\n", is1.count); + ok(is1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, is1.base_ios.sb); + ok(is1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, is1.base_ios.state); + ok(is1.base_ios.delbuf == 1, "expected 1 got %d\n", is1.base_ios.delbuf); + ok(is1.base_ios.tie == NULL, "expected %p got %p\n", NULL, is1.base_ios.tie); + ok(is1.base_ios.flags == FLAGS_skipws, "expected %x got %x\n", FLAGS_skipws, is1.base_ios.flags); + ok(is1.base_ios.precision == 6, "expected 6 got %d\n", is1.base_ios.precision); + ok(is1.base_ios.fill == ' ', "expected 32 got %d\n", is1.base_ios.fill); + ok(is1.base_ios.width == 0, "expected 0 got %d\n", is1.base_ios.width); + ok(is1.base_ios.do_lock == -1, "expected -1 got %d\n", is1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == NULL, "wrong buffer, expected %p got %p\n", NULL, pssb->base.base); + ok(pssb->base.ebuf == (char*) 0x7fffffff || pssb->base.ebuf == (char*) -1, + "wrong buffer end, expected 0x7fffffff or -1, got %p\n", pssb->base.ebuf); + ok(pssb->base.eback == NULL, "wrong get base, expected %p got %p\n", NULL, pssb->base.eback); + ok(pssb->base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, pssb->base.gptr); + ok(pssb->base.egptr == (char*) 0x7fffffff || pssb->base.egptr == (char*) -1, + "wrong get end, expected 0x7fffffff or -1, got %p\n", pssb->base.egptr); + ok(pssb->base.pbase == NULL, "wrong put base, expected %p got %p\n", NULL, pssb->base.pbase); + ok(pssb->base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, pssb->base.pptr); + ok(pssb->base.epptr == NULL, "wrong put end, expected %p got %p\n", NULL, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_istrstream_vbase_dtor, &is1); + ok(is1.base_ios.sb == NULL, "expected %p got %p\n", NULL, is1.base_ios.sb); + ok(is1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, is1.base_ios.state); + is1.extract_delim = is1.count = 0xabababab; + memset(&is1.base_ios, 0xab, sizeof(ios)); + is1.base_ios.delbuf = 0; + strcpy(buffer, "Test"); + pis = call_func4(p_istrstream_buffer_ctor, &is1, buffer, 0, FALSE); + pssb = (strstreambuf*) is1.base_ios.sb; + ok(pis == &is1, "wrong return, expected %p got %p\n", &is1, pis); + ok(is1.extract_delim == 0, "expected 0 got %d\n", is1.extract_delim); + ok(is1.count == 0, "expected 0 got %d\n", is1.count); + ok(is1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, is1.base_ios.sb); + ok(is1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, is1.base_ios.state); + ok(is1.base_ios.delbuf == 1, "expected 1 got %d\n", is1.base_ios.delbuf); + ok(is1.base_ios.tie == is2.base_ios.tie, "expected %p got %p\n", is2.base_ios.tie, is1.base_ios.tie); + ok(is1.base_ios.flags == 0xabababab, "expected %x got %x\n", 0xabababab, is1.base_ios.flags); + ok(is1.base_ios.precision == 0xabababab, "expected %d got %d\n", 0xabababab, is1.base_ios.precision); + ok(is1.base_ios.fill == (char) 0xab, "expected -85 got %d\n", is1.base_ios.fill); + ok(is1.base_ios.width == 0xabababab, "expected %d got %d\n", 0xabababab, is1.base_ios.width); + ok(is1.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, is1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); + ok(pssb->base.ebuf == buffer + 4, "wrong buffer end, expected %p got %p\n", buffer + 4, pssb->base.ebuf); + ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); + ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); + ok(pssb->base.egptr == buffer + 4, "wrong get end, expected %p got %p\n", buffer + 4, pssb->base.egptr); + ok(pssb->base.pbase == NULL, "wrong put base, expected %p got %p\n", NULL, pssb->base.pbase); + ok(pssb->base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, pssb->base.pptr); + ok(pssb->base.epptr == NULL, "wrong put end, expected %p got %p\n", NULL, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_istrstream_dtor, &is1.base_ios); + ok(is1.base_ios.sb == &pssb->base, "expected %p got %p\n", &pssb->base, is1.base_ios.sb); + ok(is1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, is1.base_ios.state); + call_func1(p_strstreambuf_dtor, pssb); + p_operator_delete(pssb); + + memset(&is1, 0xab, sizeof(istream)); + buffer[0] = 0; + pis = call_func3(p_istrstream_str_ctor, &is1, buffer, TRUE); + pssb = (strstreambuf*) is1.base_ios.sb; + ok(pis == &is1, "wrong return, expected %p got %p\n", &is1, pis); + ok(is1.extract_delim == 0, "expected 0 got %d\n", is1.extract_delim); + ok(is1.count == 0, "expected 0 got %d\n", is1.count); + ok(is1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, is1.base_ios.sb); + ok(is1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, is1.base_ios.state); + ok(is1.base_ios.delbuf == 1, "expected 1 got %d\n", is1.base_ios.delbuf); + ok(is1.base_ios.tie == NULL, "expected %p got %p\n", NULL, is1.base_ios.tie); + ok(is1.base_ios.flags == FLAGS_skipws, "expected %x got %x\n", FLAGS_skipws, is1.base_ios.flags); + ok(is1.base_ios.precision == 6, "expected 6 got %d\n", is1.base_ios.precision); + ok(is1.base_ios.fill == ' ', "expected 32 got %d\n", is1.base_ios.fill); + ok(is1.base_ios.width == 0, "expected 0 got %d\n", is1.base_ios.width); + ok(is1.base_ios.do_lock == -1, "expected -1 got %d\n", is1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); + ok(pssb->base.ebuf == buffer, "wrong buffer end, expected %p got %p\n", buffer, pssb->base.ebuf); + ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); + ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); + ok(pssb->base.egptr == buffer, "wrong get end, expected %p got %p\n", buffer, pssb->base.egptr); + ok(pssb->base.pbase == NULL, "wrong put base, expected %p got %p\n", NULL, pssb->base.pbase); + ok(pssb->base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, pssb->base.pptr); + ok(pssb->base.epptr == NULL, "wrong put end, expected %p got %p\n", NULL, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_istrstream_vbase_dtor, &is1); + ok(is1.base_ios.sb == NULL, "expected %p got %p\n", NULL, is1.base_ios.sb); + ok(is1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, is1.base_ios.state); + if (0) /* crashes on native */ + pis = call_func3(p_istrstream_str_ctor, &is1, NULL, TRUE); + is1.extract_delim = is1.count = 0xabababab; + memset(&is1.base_ios, 0xab, sizeof(ios)); + is1.base_ios.delbuf = 0; + pis = call_func3(p_istrstream_str_ctor, &is1, buffer, FALSE); + pssb = (strstreambuf*) is1.base_ios.sb; + ok(pis == &is1, "wrong return, expected %p got %p\n", &is1, pis); + ok(is1.extract_delim == 0, "expected 0 got %d\n", is1.extract_delim); + ok(is1.count == 0, "expected 0 got %d\n", is1.count); + ok(is1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, is1.base_ios.sb); + ok(is1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, is1.base_ios.state); + ok(is1.base_ios.delbuf == 1, "expected 1 got %d\n", is1.base_ios.delbuf); + ok(is1.base_ios.tie == is2.base_ios.tie, "expected %p got %p\n", is2.base_ios.tie, is1.base_ios.tie); + ok(is1.base_ios.flags == 0xabababab, "expected %x got %x\n", 0xabababab, is1.base_ios.flags); + ok(is1.base_ios.precision == 0xabababab, "expected %d got %d\n", 0xabababab, is1.base_ios.precision); + ok(is1.base_ios.fill == (char) 0xab, "expected -85 got %d\n", is1.base_ios.fill); + ok(is1.base_ios.width == 0xabababab, "expected %d got %d\n", 0xabababab, is1.base_ios.width); + ok(is1.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, is1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); + ok(pssb->base.ebuf == buffer, "wrong buffer end, expected %p got %p\n", buffer, pssb->base.ebuf); + ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); + ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); + ok(pssb->base.egptr == buffer, "wrong get end, expected %p got %p\n", buffer, pssb->base.egptr); + ok(pssb->base.pbase == NULL, "wrong put base, expected %p got %p\n", NULL, pssb->base.pbase); + ok(pssb->base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, pssb->base.pptr); + ok(pssb->base.epptr == NULL, "wrong put end, expected %p got %p\n", NULL, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_istrstream_dtor, &is1.base_ios); + ok(is1.base_ios.sb == &pssb->base, "expected %p got %p\n", &pssb->base, is1.base_ios.sb); + ok(is1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, is1.base_ios.state); + call_func1(p_strstreambuf_dtor, pssb); + p_operator_delete(pssb); + + is1.extract_delim = is1.count = 0xcdcdcdcd; + memset(&is1.base_ios, 0xcd, sizeof(ios)); + pis = call_func3(p_istrstream_copy_ctor, &is2, &is1, TRUE); + ok(pis == &is2, "wrong return, expected %p got %p\n", &is2, pis); + ok(is2.extract_delim == 0, "expected 0 got %d\n", is2.extract_delim); + ok(is2.count == 0, "expected 0 got %d\n", is2.count); + ok(is2.base_ios.sb == is1.base_ios.sb, "expected %p got %p\n", is1.base_ios.sb, is2.base_ios.sb); + ok(is2.base_ios.state == 0xcdcdcdc9, "expected %d got %d\n", 0xcdcdcdc9, is2.base_ios.state); + ok(is2.base_ios.delbuf == 0, "expected 0 got %d\n", is2.base_ios.delbuf); + ok(is2.base_ios.tie == is1.base_ios.tie, "expected %p got %p\n", is1.base_ios.tie, is2.base_ios.tie); + ok(is2.base_ios.flags == 0xcdcdcdcd, "expected %x got %x\n", 0xcdcdcdcd, is2.base_ios.flags); + ok(is2.base_ios.precision == (char) 0xcd, "expected -51 got %d\n", is2.base_ios.precision); + ok(is2.base_ios.fill == (char) 0xcd, "expected -51 got %d\n", is2.base_ios.fill); + ok(is2.base_ios.width == (char) 0xcd, "expected -51 got %d\n", is2.base_ios.width); + ok(is2.base_ios.do_lock == -1, "expected -1 got %d\n", is2.base_ios.do_lock); + call_func1(p_istrstream_vbase_dtor, &is2); + ok(is2.base_ios.sb == NULL, "expected %p got %p\n", NULL, is2.base_ios.sb); + ok(is2.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, is2.base_ios.state); + is2.extract_delim = is2.count = 0xabababab; + memset(&is2.base_ios, 0xab, sizeof(ios)); + is2.base_ios.delbuf = 0; + pos = is2.base_ios.tie; + pis = call_func3(p_istrstream_copy_ctor, &is2, &is1, FALSE); + ok(pis == &is2, "wrong return, expected %p got %p\n", &is2, pis); + ok(is2.extract_delim == 0, "expected 0 got %d\n", is2.extract_delim); + ok(is2.count == 0, "expected 0 got %d\n", is2.count); + ok(is2.base_ios.sb == is1.base_ios.sb, "expected %p got %p\n", is1.base_ios.sb, is2.base_ios.sb); + ok(is2.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, is2.base_ios.state); + ok(is2.base_ios.delbuf == 0, "expected 0 got %d\n", is2.base_ios.delbuf); + ok(is2.base_ios.tie == pos, "expected %p got %p\n", pos, is2.base_ios.tie); + ok(is2.base_ios.flags == 0xabababab, "expected %x got %x\n", 0xabababab, is2.base_ios.flags); + ok(is2.base_ios.precision == 0xabababab, "expected %d got %d\n", 0xabababab, is2.base_ios.precision); + ok(is2.base_ios.fill == (char) 0xab, "expected -85 got %d\n", is2.base_ios.fill); + ok(is2.base_ios.width == 0xabababab, "expected %d got %d\n", 0xabababab, is2.base_ios.width); + ok(is2.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, is2.base_ios.do_lock); + call_func1(p_istrstream_dtor, &is2.base_ios); + + /* assignment */ + is2.extract_delim = is2.count = 0xabababab; + memset(&is2.base_ios, 0xab, sizeof(ios)); + is2.base_ios.delbuf = 0; + pis = call_func2(p_istrstream_assign, &is2, &is1); + ok(pis == &is2, "wrong return, expected %p got %p\n", &is2, pis); + ok(is2.extract_delim == 0xabababab, "expected %d got %d\n", 0xabababab, is2.extract_delim); + ok(is2.count == 0, "expected 0 got %d\n", is2.count); + ok(is2.base_ios.sb == is1.base_ios.sb, "expected %p got %p\n", is1.base_ios.sb, is2.base_ios.sb); + ok(is2.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, is2.base_ios.state); + ok(is2.base_ios.delbuf == 0, "expected 0 got %d\n", is2.base_ios.delbuf); + ok(is2.base_ios.tie == NULL, "expected %p got %p\n", NULL, is2.base_ios.tie); + ok(is2.base_ios.flags == FLAGS_skipws, "expected %x got %x\n", FLAGS_skipws, is2.base_ios.flags); + ok(is2.base_ios.precision == 6, "expected 6 got %d\n", is2.base_ios.precision); + ok(is2.base_ios.fill == ' ', "expected 32 got %d\n", is2.base_ios.fill); + ok(is2.base_ios.width == 0, "expected 0 got %d\n", is2.base_ios.width); + ok(is2.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, is2.base_ios.do_lock); +} + static void test_iostream(void) { iostream ios1, ios2, *pios; @@ -6693,6 +6952,7 @@ START_TEST(msvcirt) test_istream_getdouble(); test_istream_read(); test_istream_withassign(); + test_istrstream(); test_iostream(); test_Iostream_init(); test_std_streams(); -- 2.7.4 From jacek at codeweavers.com Wed Oct 19 07:04:19 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 19 Oct 2016 14:04:19 +0200 Subject: [PATCH 1/2] taskschd: Added ITriggerCollection::Create implementation. Message-ID: Signed-off-by: Jacek Caban --- dlls/taskschd/task.c | 263 +++++++++++++++++++++++++++++++++++++++- dlls/taskschd/tests/scheduler.c | 18 +++ 2 files changed, 279 insertions(+), 2 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-taskschd-Added-ITriggerCollection-Create-implementati.diff Type: text/x-patch Size: 10312 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 19 07:04:32 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 19 Oct 2016 14:04:32 +0200 Subject: [PATCH 2/2] taskschd: Added IDailyTrigger::DaysInterval property implementation. Message-ID: Signed-off-by: Jacek Caban --- dlls/taskschd/task.c | 19 +++++++++++++++---- dlls/taskschd/tests/scheduler.c | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-taskschd-Added-IDailyTrigger-DaysInterval-property-im.diff Type: text/x-patch Size: 3087 bytes Desc: not available URL: From matellanesivan at gmail.com Wed Oct 19 07:00:52 2016 From: matellanesivan at gmail.com (=?UTF-8?q?Iv=C3=A1n=20Matellanes?=) Date: Wed, 19 Oct 2016 14:00:52 +0200 Subject: [2/6] msvcirt: Add a partial implementation of class ostrstream. In-Reply-To: <1476878456-8303-1-git-send-email-matellanesivan@gmail.com> References: <1476878456-8303-1-git-send-email-matellanesivan@gmail.com> Message-ID: <1476878456-8303-2-git-send-email-matellanesivan@gmail.com> Signed-off-by: Iván Matellanes --- dlls/msvcirt/msvcirt.c | 85 +++++++++++++++++++++++++++++++++++---------- dlls/msvcirt/msvcirt.spec | 44 +++++++++++------------ dlls/msvcrt20/msvcrt20.spec | 36 +++++++++---------- dlls/msvcrt40/msvcrt40.spec | 36 +++++++++---------- 4 files changed, 125 insertions(+), 76 deletions(-) diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index e9103a9..ebbe442 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -185,6 +185,8 @@ extern const vtable_ptr MSVCP_ios_vtable; extern const vtable_ptr MSVCP_ostream_vtable; /* ??_7ostream_withassign@@6B@ */ extern const vtable_ptr MSVCP_ostream_withassign_vtable; +/* ??_7ostrstream@@6B@ */ +extern const vtable_ptr MSVCP_ostrstream_vtable; /* ??_7istream@@6B@ */ extern const vtable_ptr MSVCP_istream_vtable; /* ??_7istream_withassign@@6B@ */ @@ -249,6 +251,8 @@ void __asm_dummy_vtables(void) { VTABLE_ADD_FUNC(ostream_vector_dtor)); __ASM_VTABLE(ostream_withassign, VTABLE_ADD_FUNC(ostream_vector_dtor)); + __ASM_VTABLE(ostrstream, + VTABLE_ADD_FUNC(ostream_vector_dtor)); __ASM_VTABLE(istream, VTABLE_ADD_FUNC(istream_vector_dtor)); __ASM_VTABLE(istream_withassign, @@ -264,6 +268,7 @@ void __asm_dummy_vtables(void) { /* ??_8ostream@@7B@ */ /* ??_8ostream_withassign@@7B@ */ +/* ??_8ostrstream@@7B@ */ const int ostream_vbtable[] = {0, VBTABLE_ENTRY(ostream, FIELD_OFFSET(ostream, vbtable), ios)}; /* ??_8istream@@7B@ */ /* ??_8istream_withassign@@7B@ */ @@ -281,6 +286,8 @@ DEFINE_RTTI_DATA0(ios, 0, ".?AVios@@") DEFINE_RTTI_DATA1(ostream, sizeof(ostream), &ios_rtti_base_descriptor, ".?AVostream@@") DEFINE_RTTI_DATA2(ostream_withassign, sizeof(ostream), &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVostream_withassign@@") +DEFINE_RTTI_DATA2(ostrstream, sizeof(ostream), + &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVostrstream@@") DEFINE_RTTI_DATA1(istream, sizeof(istream), &ios_rtti_base_descriptor, ".?AVistream@@") DEFINE_RTTI_DATA2(istream_withassign, sizeof(istream), &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVistream_withassign@@") @@ -2349,6 +2356,8 @@ ostream* __thiscall ostream_copy_ctor(ostream *this, const ostream *copy, BOOL v /* ??1ostream@@UEAA at XZ */ /* ??1ostream_withassign@@UAE at XZ */ /* ??1ostream_withassign@@UEAA at XZ */ +/* ??1ostrstream@@UAE at XZ */ +/* ??1ostrstream@@UEAA at XZ */ DEFINE_THISCALL_WRAPPER(ostream_dtor, 4) void __thiscall ostream_dtor(ios *base) { @@ -2385,6 +2394,8 @@ ostream* __thiscall ostream_assign_sb(ostream *this, streambuf *sb) /* ??4ostream_withassign@@QEAAAEAV0 at AEBV0@@Z */ /* ??4ostream_withassign@@QAEAAVostream@@ABV1@@Z */ /* ??4ostream_withassign@@QEAAAEAVostream@@AEBV1@@Z */ +/* ??4ostrstream@@QAEAAV0 at ABV0@@Z */ +/* ??4ostrstream@@QEAAAEAV0 at AEBV0@@Z */ DEFINE_THISCALL_WRAPPER(ostream_assign, 8) ostream* __thiscall ostream_assign(ostream *this, const ostream *rhs) { @@ -2395,6 +2406,8 @@ ostream* __thiscall ostream_assign(ostream *this, const ostream *rhs) /* ??_Dostream@@QEAAXXZ */ /* ??_Dostream_withassign@@QAEXXZ */ /* ??_Dostream_withassign@@QEAAXXZ */ +/* ??_Dostrstream@@QAEXXZ */ +/* ??_Dostrstream@@QEAAXXZ */ DEFINE_THISCALL_WRAPPER(ostream_vbase_dtor, 4) void __thiscall ostream_vbase_dtor(ostream *this) { @@ -2408,6 +2421,7 @@ void __thiscall ostream_vbase_dtor(ostream *this) /* ??_Eostream@@UAEPAXI at Z */ /* ??_Eostream_withassign@@UAEPAXI at Z */ +/* ??_Eostrstream@@UAEPAXI at Z */ DEFINE_THISCALL_WRAPPER(ostream_vector_dtor, 8) ostream* __thiscall ostream_vector_dtor(ios *base, unsigned int flags) { @@ -2432,6 +2446,7 @@ ostream* __thiscall ostream_vector_dtor(ios *base, unsigned int flags) /* ??_Gostream@@UAEPAXI at Z */ /* ??_Gostream_withassign@@UAEPAXI at Z */ +/* ??_Gostrstream@@UAEPAXI at Z */ DEFINE_THISCALL_WRAPPER(ostream_scalar_dtor, 8) ostream* __thiscall ostream_scalar_dtor(ios *base, unsigned int flags) { @@ -2936,6 +2951,57 @@ ostream* __thiscall ostream_withassign_ctor(ostream *this, BOOL virt_init) return this; } +/* ??0ostrstream@@QAE at ABV0@@Z */ +/* ??0ostrstream@@QEAA at AEBV0@@Z */ +DEFINE_THISCALL_WRAPPER(ostrstream_copy_ctor, 12) +ostream* __thiscall ostrstream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init) +{ + FIXME("(%p %p %d) stub\n", this, copy, virt_init); + return this; +} + +/* ??0ostrstream@@QAE at PADHH@Z */ +/* ??0ostrstream@@QEAA at PEADHH@Z */ +DEFINE_THISCALL_WRAPPER(ostrstream_buffer_ctor, 20) +ostream* __thiscall ostrstream_buffer_ctor(ostream *this, char *buffer, int length, int mode, BOOL virt_init) +{ + FIXME("(%p %p %d %d %d) stub\n", this, buffer, length, mode, virt_init); + return this; +} + +/* ??0ostrstream@@QAE at XZ */ +/* ??0ostrstream@@QEAA at XZ */ +DEFINE_THISCALL_WRAPPER(ostrstream_ctor, 8) +ostream* __thiscall ostrstream_ctor(ostream *this, BOOL virt_init) +{ + FIXME("(%p %d) stub\n", this, virt_init); + return this; +} + +/* ?pcount at ostrstream@@QBEHXZ */ +/* ?pcount at ostrstream@@QEBAHXZ */ +DEFINE_THISCALL_WRAPPER(ostrstream_pcount, 4) +int __thiscall ostrstream_pcount(const ostream *this) +{ + return streambuf_out_waiting(ostream_get_ios(this)->sb); +} + +/* ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ */ +/* ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ */ +DEFINE_THISCALL_WRAPPER(ostrstream_rdbuf, 4) +strstreambuf* __thiscall ostrstream_rdbuf(const ostream *this) +{ + return (strstreambuf*) ostream_get_ios(this)->sb; +} + +/* ?str at ostrstream@@QAEPADXZ */ +/* ?str at ostrstream@@QEAAPEADXZ */ +DEFINE_THISCALL_WRAPPER(ostrstream_str, 4) +char* __thiscall ostrstream_str(ostream *this) +{ + return strstreambuf_str(ostrstream_rdbuf(this)); +} + static inline ios* istream_get_ios(const istream *this) { return (ios*)((char*)this + this->vbtable[1]); @@ -4132,24 +4198,6 @@ void __cdecl ios_sync_with_stdio(void) } } -/****************************************************************** - * ??0ostrstream@@QAE at XZ (MSVCRTI.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_ctor,8) -void * __thiscall MSVCIRT_ostrstream_ctor(ostream *this, BOOL virt_init) -{ - FIXME("(%p %x) stub\n", this, virt_init); - return this; -} - -/****************************************************************** - * ??1ostrstream@@UAE at XZ (MSVCRTI.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_dtor,4) -void __thiscall MSVCIRT_ostrstream_dtor(ios *base) -{ - FIXME("(%p) stub\n", base); -} #ifdef __i386__ @@ -4210,6 +4258,7 @@ static void init_io(void *base) init_ios_rtti(base); init_ostream_rtti(base); init_ostream_withassign_rtti(base); + init_ostrstream_rtti(base); init_istream_rtti(base); init_istream_withassign_rtti(base); init_iostream_rtti(base); diff --git a/dlls/msvcirt/msvcirt.spec b/dlls/msvcirt/msvcirt.spec index f9ed8de..5b09a3d 100644 --- a/dlls/msvcirt/msvcirt.spec +++ b/dlls/msvcirt/msvcirt.spec @@ -92,12 +92,12 @@ @ cdecl -arch=win64 ??0ostream_withassign@@QEAA at PEAVstreambuf@@@Z(ptr ptr long) ostream_withassign_sb_ctor @ thiscall -arch=win32 ??0ostream_withassign@@QAE at XZ(ptr long) ostream_withassign_ctor @ cdecl -arch=win64 ??0ostream_withassign@@QEAA at XZ(ptr long) ostream_withassign_ctor -@ stub -arch=win32 ??0ostrstream@@QAE at ABV0@@Z # __thiscall ostrstream::ostrstream(class ostrstream const &) -@ stub -arch=win64 ??0ostrstream@@QEAA at AEBV0@@Z -@ stub -arch=win32 ??0ostrstream@@QAE at PADHH@Z # __thiscall ostrstream::ostrstream(char *,int,int) -@ stub -arch=win64 ??0ostrstream@@QEAA at PEADHH@Z -@ thiscall -arch=win32 ??0ostrstream@@QAE at XZ(ptr long) MSVCIRT_ostrstream_ctor -@ cdecl -arch=win64 ??0ostrstream@@QEAA at XZ(ptr long) MSVCIRT_ostrstream_ctor +@ thiscall -arch=win32 ??0ostrstream@@QAE at ABV0@@Z(ptr ptr long) ostrstream_copy_ctor +@ cdecl -arch=win64 ??0ostrstream@@QEAA at AEBV0@@Z(ptr ptr long) ostrstream_copy_ctor +@ thiscall -arch=win32 ??0ostrstream@@QAE at PADHH@Z(ptr ptr long long long) ostrstream_buffer_ctor +@ cdecl -arch=win64 ??0ostrstream@@QEAA at PEADHH@Z(ptr ptr long long long) ostrstream_buffer_ctor +@ thiscall -arch=win32 ??0ostrstream@@QAE at XZ(ptr long) ostrstream_ctor +@ cdecl -arch=win64 ??0ostrstream@@QEAA at XZ(ptr long) ostrstream_ctor @ thiscall -arch=win32 ??0stdiobuf@@QAE at ABV0@@Z(ptr ptr) stdiobuf_copy_ctor @ cdecl -arch=win64 ??0stdiobuf@@QEAA at AEBV0@@Z(ptr ptr) stdiobuf_copy_ctor @ thiscall -arch=win32 ??0stdiobuf@@QAE at PAU_iobuf@@@Z(ptr ptr) stdiobuf_file_ctor @@ -158,8 +158,8 @@ @ cdecl -arch=win64 ??1ostream@@UEAA at XZ(ptr) ostream_dtor @ thiscall -arch=win32 ??1ostream_withassign@@UAE at XZ(ptr) ostream_dtor @ cdecl -arch=win64 ??1ostream_withassign@@UEAA at XZ(ptr) ostream_dtor -@ thiscall -arch=win32 ??1ostrstream@@UAE at XZ(ptr) MSVCIRT_ostrstream_dtor -@ cdecl -arch=win64 ??1ostrstream@@UEAA at XZ(ptr) MSVCIRT_ostrstream_dtor +@ thiscall -arch=win32 ??1ostrstream@@UAE at XZ(ptr) ostream_dtor +@ cdecl -arch=win64 ??1ostrstream@@UEAA at XZ(ptr) ostream_dtor @ thiscall -arch=win32 ??1stdiobuf@@UAE at XZ(ptr) stdiobuf_dtor @ cdecl -arch=win64 ??1stdiobuf@@UEAA at XZ(ptr) stdiobuf_dtor @ stub -arch=win32 ??1stdiostream@@UAE at XZ # virtual __thiscall stdiostream::~stdiostream(void) @@ -212,8 +212,8 @@ @ cdecl -arch=win64 ??4ostream_withassign@@QEAAAEAVostream@@AEBV1@@Z(ptr ptr) ostream_assign @ thiscall -arch=win32 ??4ostream_withassign@@QAEAAVostream@@PAVstreambuf@@@Z(ptr ptr) ostream_assign_sb @ cdecl -arch=win64 ??4ostream_withassign@@QEAAAEAVostream@@PEAVstreambuf@@@Z(ptr ptr) ostream_assign_sb -@ stub -arch=win32 ??4ostrstream@@QAEAAV0 at ABV0@@Z # class ostrstream & __thiscall ostrstream::operator=(class ostrstream const &) -@ stub -arch=win64 ??4ostrstream@@QEAAAEAV0 at AEBV0@@Z +@ thiscall -arch=win32 ??4ostrstream@@QAEAAV0 at ABV0@@Z(ptr ptr) ostream_assign +@ cdecl -arch=win64 ??4ostrstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) ostream_assign @ thiscall -arch=win32 ??4stdiobuf@@QAEAAV0 at ABV0@@Z(ptr ptr) stdiobuf_assign @ cdecl -arch=win64 ??4stdiobuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) stdiobuf_assign @ stub -arch=win32 ??4stdiostream@@QAEAAV0 at AAV0@@Z # class stdiostream & __thiscall stdiostream::operator=(class stdiostream &) @@ -315,7 +315,7 @@ # @ extern ??_7ofstream@@6B@ # const ofstream::`vftable' @ extern ??_7ostream@@6B@ MSVCP_ostream_vtable @ extern ??_7ostream_withassign@@6B@ MSVCP_ostream_withassign_vtable -# @ extern ??_7ostrstream@@6B@ # const ostrstream::`vftable' +@ extern ??_7ostrstream@@6B@ MSVCP_ostrstream_vtable @ extern ??_7stdiobuf@@6B@ MSVCP_stdiobuf_vtable # @ extern ??_7stdiostream@@6B@ # const stdiostream::`vftable' @ extern ??_7streambuf@@6B@ MSVCP_streambuf_vtable @@ -332,7 +332,7 @@ # @ extern ??_8ofstream@@7B@ # const ofstream::`vbtable' @ extern ??_8ostream@@7B@ ostream_vbtable @ extern ??_8ostream_withassign@@7B@ ostream_vbtable -# @ extern ??_8ostrstream@@7B@ # const ostrstream::`vbtable' +@ extern ??_8ostrstream@@7B@ ostream_vbtable # @ extern ??_8stdiostream@@7Bistream@@@ # const stdiostream::`vbtable'{for `istream'} # @ extern ??_8stdiostream@@7Bostream@@@ # const stdiostream::`vbtable'{for `ostream'} # @ extern ??_8strstream@@7Bistream@@@ # const strstream::`vbtable'{for `istream'} @@ -355,8 +355,8 @@ @ cdecl -arch=win64 ??_Dostream@@QEAAXXZ(ptr) ostream_vbase_dtor @ thiscall -arch=win32 ??_Dostream_withassign@@QAEXXZ(ptr) ostream_vbase_dtor @ cdecl -arch=win64 ??_Dostream_withassign@@QEAAXXZ(ptr) ostream_vbase_dtor -@ stub -arch=win32 ??_Dostrstream@@QAEXXZ # void __thiscall ostrstream::`vbase destructor'(void) -@ stub -arch=win64 ??_Dostrstream@@QEAAXXZ +@ thiscall -arch=win32 ??_Dostrstream@@QAEXXZ(ptr) ostream_vbase_dtor +@ cdecl -arch=win64 ??_Dostrstream@@QEAAXXZ(ptr) ostream_vbase_dtor @ stub -arch=win32 ??_Dstdiostream@@QAEXXZ # void __thiscall stdiostream::`vbase destructor'(void) @ stub -arch=win64 ??_Dstdiostream@@QEAAXXZ @ stub -arch=win32 ??_Dstrstream@@QAEXXZ # void __thiscall strstream::`vbase destructor'(void) @@ -374,7 +374,7 @@ @ stub -arch=win32 ??_Eofstream@@UAEPAXI at Z # virtual void * __thiscall ofstream::`vector deleting destructor'(unsigned int) @ thiscall -arch=win32 ??_Eostream@@UAEPAXI at Z(ptr long) ostream_vector_dtor @ thiscall -arch=win32 ??_Eostream_withassign@@UAEPAXI at Z(ptr long) ostream_vector_dtor -@ stub -arch=win32 ??_Eostrstream@@UAEPAXI at Z # virtual void * __thiscall ostrstream::`vector deleting destructor'(unsigned int) +@ thiscall -arch=win32 ??_Eostrstream@@UAEPAXI at Z(ptr long) ostream_vector_dtor @ thiscall -arch=win32 ??_Estdiobuf@@UAEPAXI at Z(ptr long) stdiobuf_vector_dtor @ stub -arch=win32 ??_Estdiostream@@UAEPAXI at Z # virtual void * __thiscall stdiostream::`vector deleting destructor'(unsigned int) @ thiscall -arch=win32 ??_Estreambuf@@UAEPAXI at Z(ptr long) streambuf_vector_dtor @@ -393,7 +393,7 @@ @ stub -arch=win32 ??_Gofstream@@UAEPAXI at Z # virtual void * __thiscall ofstream::`scalar deleting destructor'(unsigned int) @ thiscall -arch=win32 ??_Gostream@@UAEPAXI at Z(ptr long) ostream_scalar_dtor @ thiscall -arch=win32 ??_Gostream_withassign@@UAEPAXI at Z(ptr long) ostream_scalar_dtor -@ stub -arch=win32 ??_Gostrstream@@UAEPAXI at Z # virtual void * __thiscall ostrstream::`scalar deleting destructor'(unsigned int) +@ thiscall -arch=win32 ??_Gostrstream@@UAEPAXI at Z(ptr long) ostream_scalar_dtor @ thiscall -arch=win32 ??_Gstdiobuf@@UAEPAXI at Z(ptr long) stdiobuf_scalar_dtor @ stub -arch=win32 ??_Gstdiostream@@UAEPAXI at Z # virtual void * __thiscall stdiostream::`scalar deleting destructor'(unsigned int) @ thiscall -arch=win32 ??_Gstreambuf@@UAEPAXI at Z(ptr long) streambuf_scalar_dtor @@ -591,8 +591,8 @@ @ cdecl -arch=win64 ?pbase at streambuf@@IEBAPEADXZ(ptr) streambuf_pbase @ thiscall -arch=win32 ?pbump at streambuf@@IAEXH at Z(ptr long) streambuf_pbump @ cdecl -arch=win64 ?pbump at streambuf@@IEAAXH at Z(ptr long) streambuf_pbump -@ stub -arch=win32 ?pcount at ostrstream@@QBEHXZ # int __thiscall ostrstream::pcount(void)const -@ stub -arch=win64 ?pcount at ostrstream@@QEBAHXZ +@ thiscall -arch=win32 ?pcount at ostrstream@@QBEHXZ(ptr) ostrstream_pcount +@ cdecl -arch=win64 ?pcount at ostrstream@@QEBAHXZ(ptr) ostrstream_pcount @ stub -arch=win32 ?pcount at strstream@@QBEHXZ # int __thiscall strstream::pcount(void)const @ stub -arch=win64 ?pcount at strstream@@QEBAHXZ @ thiscall -arch=win32 ?peek at istream@@QAEHXZ(ptr) istream_peek @@ -623,8 +623,8 @@ @ stub -arch=win64 ?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ @ stub -arch=win32 ?rdbuf at ofstream@@QBEPAVfilebuf@@XZ # class filebuf * __thiscall ofstream::rdbuf(void)const @ stub -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ -@ stub -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ # class strstreambuf * __thiscall ostrstream::rdbuf(void)const -@ stub -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ +@ thiscall -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ(ptr) ostrstream_rdbuf +@ cdecl -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) ostrstream_rdbuf @ stub -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ # class stdiobuf * __thiscall stdiostream::rdbuf(void)const @ stub -arch=win64 ?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ @ stub -arch=win32 ?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ # class strstreambuf * __thiscall strstream::rdbuf(void)const @@ -714,8 +714,8 @@ @ cdecl -arch=win64 ?stossc at streambuf@@QEAAXXZ(ptr) streambuf_stossc @ stub -arch=win32 ?str at istrstream@@QAEPADXZ # char * __thiscall istrstream::str(void) @ stub -arch=win64 ?str at istrstream@@QEAAPEADXZ -@ stub -arch=win32 ?str at ostrstream@@QAEPADXZ # char * __thiscall ostrstream::str(void) -@ stub -arch=win64 ?str at ostrstream@@QEAAPEADXZ +@ thiscall -arch=win32 ?str at ostrstream@@QAEPADXZ(ptr) ostrstream_str +@ cdecl -arch=win64 ?str at ostrstream@@QEAAPEADXZ(ptr) ostrstream_str @ stub -arch=win32 ?str at strstream@@QAEPADXZ # char * __thiscall strstream::str(void) @ stub -arch=win64 ?str at strstream@@QEAAPEADXZ @ thiscall -arch=win32 ?str at strstreambuf@@QAEPADXZ(ptr) strstreambuf_str diff --git a/dlls/msvcrt20/msvcrt20.spec b/dlls/msvcrt20/msvcrt20.spec index bbc89be..237c106 100644 --- a/dlls/msvcrt20/msvcrt20.spec +++ b/dlls/msvcrt20/msvcrt20.spec @@ -82,10 +82,10 @@ @ cdecl -arch=win64 ??0ostream_withassign@@QEAA at PEAVstreambuf@@@Z(ptr ptr long) msvcirt.??0ostream_withassign@@QEAA at PEAVstreambuf@@@Z @ thiscall -arch=win32 ??0ostream_withassign@@QAE at XZ(ptr long) msvcirt.??0ostream_withassign@@QAE at XZ @ cdecl -arch=win64 ??0ostream_withassign@@QEAA at XZ(ptr long) msvcirt.??0ostream_withassign@@QEAA at XZ -@ stub -arch=win32 ??0ostrstream@@QAE at ABV0@@Z -@ stub -arch=win64 ??0ostrstream@@QEAA at AEBV0@@Z -@ stub -arch=win32 ??0ostrstream@@QAE at PADHH@Z -@ stub -arch=win64 ??0ostrstream@@QEAA at PEADHH@Z +@ thiscall -arch=win32 ??0ostrstream@@QAE at ABV0@@Z(ptr ptr long) msvcirt.??0ostrstream@@QAE at ABV0@@Z +@ cdecl -arch=win64 ??0ostrstream@@QEAA at AEBV0@@Z(ptr ptr long) msvcirt.??0ostrstream@@QEAA at AEBV0@@Z +@ thiscall -arch=win32 ??0ostrstream@@QAE at PADHH@Z(ptr ptr long long long) msvcirt.??0ostrstream@@QAE at PADHH@Z +@ cdecl -arch=win64 ??0ostrstream@@QEAA at PEADHH@Z(ptr ptr long long long) msvcirt.??0ostrstream@@QEAA at PEADHH@Z @ thiscall -arch=win32 ??0ostrstream@@QAE at XZ(ptr long) msvcirt.??0ostrstream@@QAE at XZ @ cdecl -arch=win64 ??0ostrstream@@QEAA at XZ(ptr long) msvcirt.??0ostrstream@@QEAA at XZ @ thiscall -arch=win32 ??0stdiobuf@@QAE at ABV0@@Z(ptr ptr) msvcirt.??0stdiobuf@@QAE at ABV0@@Z @@ -196,8 +196,8 @@ @ cdecl -arch=win64 ??4ostream_withassign@@QEAAAEAVostream@@AEBV1@@Z(ptr ptr) msvcirt.??4ostream_withassign@@QEAAAEAVostream@@AEBV1@@Z @ thiscall -arch=win32 ??4ostream_withassign@@QAEAAVostream@@PAVstreambuf@@@Z(ptr ptr) msvcirt.??4ostream_withassign@@QAEAAVostream@@PAVstreambuf@@@Z @ cdecl -arch=win64 ??4ostream_withassign@@QEAAAEAVostream@@PEAVstreambuf@@@Z(ptr ptr) msvcirt.??4ostream_withassign@@QEAAAEAVostream@@PEAVstreambuf@@@Z -@ stub -arch=win32 ??4ostrstream@@QAEAAV0 at ABV0@@Z -@ stub -arch=win64 ??4ostrstream@@QEAAAEAV0 at AEBV0@@Z +@ thiscall -arch=win32 ??4ostrstream@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4ostrstream@@QAEAAV0 at ABV0@@Z +@ cdecl -arch=win64 ??4ostrstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4ostrstream@@QEAAAEAV0 at AEBV0@@Z @ thiscall -arch=win32 ??4stdiobuf@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4stdiobuf@@QAEAAV0 at ABV0@@Z @ cdecl -arch=win64 ??4stdiobuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4stdiobuf@@QEAAAEAV0 at AEBV0@@Z @ stub -arch=win32 ??4stdiostream@@QAEAAV0 at AAV0@@Z @@ -297,7 +297,7 @@ # @ extern ??_7ofstream@@6B@ @ extern ??_7ostream@@6B@ msvcirt.??_7ostream@@6B@ @ extern ??_7ostream_withassign@@6B@ msvcirt.??_7ostream_withassign@@6B@ -# @ extern ??_7ostrstream@@6B@ +@ extern ??_7ostrstream@@6B@ msvcirt.??_7ostrstream@@6B@ @ extern ??_7stdiobuf@@6B@ msvcirt.??_7stdiobuf@@6B@ # @ extern ??_7stdiostream@@6B@ @ extern ??_7streambuf@@6B@ msvcirt.??_7streambuf@@6B@ @@ -314,7 +314,7 @@ # @ extern ??_8ofstream@@7B@ @ extern ??_8ostream@@7B@ msvcirt.??_8ostream@@7B@ @ extern ??_8ostream_withassign@@7B@ msvcirt.??_8ostream_withassign@@7B@ -# @ extern ??_8ostrstream@@7B@ +@ extern ??_8ostrstream@@7B@ msvcirt.??_8ostrstream@@7B@ # @ extern ??_8stdiostream@@7Bistream@@@ # @ extern ??_8stdiostream@@7Bostream@@@ # @ extern ??_8strstream@@7Bistream@@@ @@ -337,8 +337,8 @@ @ cdecl -arch=win64 ??_Dostream@@QEAAXXZ(ptr) msvcirt.??_Dostream@@QEAAXXZ @ thiscall -arch=win32 ??_Dostream_withassign@@QAEXXZ(ptr) msvcirt.??_Dostream_withassign@@QAEXXZ @ cdecl -arch=win64 ??_Dostream_withassign@@QEAAXXZ(ptr) msvcirt.??_Dostream_withassign@@QEAAXXZ -@ stub -arch=win32 ??_Dostrstream@@QAEXXZ -@ stub -arch=win64 ??_Dostrstream@@QEAAXXZ +@ thiscall -arch=win32 ??_Dostrstream@@QAEXXZ(ptr) msvcirt.??_Dostrstream@@QAEXXZ +@ cdecl -arch=win64 ??_Dostrstream@@QEAAXXZ(ptr) msvcirt.??_Dostrstream@@QEAAXXZ @ stub -arch=win32 ??_Dstdiostream@@QAEXXZ @ stub -arch=win64 ??_Dstdiostream@@QEAAXXZ @ stub -arch=win32 ??_Dstrstream@@QAEXXZ @@ -355,7 +355,7 @@ @ stub -arch=win32 ??_Eofstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Eostream@@UAEPAXI at Z(ptr long) msvcirt.??_Eostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Eostream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Eostream_withassign@@UAEPAXI at Z -@ stub -arch=win32 ??_Eostrstream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Eostrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Eostrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estdiobuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estdiobuf@@UAEPAXI at Z @ stub -arch=win32 ??_Estdiostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estreambuf@@UAEPAXI at Z @@ -373,7 +373,7 @@ @ stub -arch=win32 ??_Gofstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gostream@@UAEPAXI at Z(ptr long) msvcirt.??_Gostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gostream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Gostream_withassign@@UAEPAXI at Z -@ stub -arch=win32 ??_Gostrstream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Gostrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gostrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstdiobuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstdiobuf@@UAEPAXI at Z @ stub -arch=win32 ??_Gstdiostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstreambuf@@UAEPAXI at Z @@ -577,8 +577,8 @@ @ cdecl -arch=win64 ?pbase at streambuf@@IEBAPEADXZ(ptr) msvcirt.?pbase at streambuf@@IEBAPEADXZ @ thiscall -arch=win32 ?pbump at streambuf@@IAEXH at Z(ptr long) msvcirt.?pbump at streambuf@@IAEXH at Z @ cdecl -arch=win64 ?pbump at streambuf@@IEAAXH at Z(ptr long) msvcirt.?pbump at streambuf@@IEAAXH at Z -@ stub -arch=win32 ?pcount at ostrstream@@QBEHXZ -@ stub -arch=win64 ?pcount at ostrstream@@QEBAHXZ +@ thiscall -arch=win32 ?pcount at ostrstream@@QBEHXZ(ptr) msvcirt.?pcount at ostrstream@@QBEHXZ +@ cdecl -arch=win64 ?pcount at ostrstream@@QEBAHXZ(ptr) msvcirt.?pcount at ostrstream@@QEBAHXZ @ stub -arch=win32 ?pcount at strstream@@QBEHXZ @ stub -arch=win64 ?pcount at strstream@@QEBAHXZ @ thiscall -arch=win32 ?peek at istream@@QAEHXZ(ptr) msvcirt.?peek at istream@@QAEHXZ @@ -609,8 +609,8 @@ @ stub -arch=win64 ?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ @ stub -arch=win32 ?rdbuf at ofstream@@QBEPAVfilebuf@@XZ @ stub -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ -@ stub -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ -@ stub -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ +@ thiscall -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ +@ cdecl -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ @ stub -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ @ stub -arch=win64 ?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ @ stub -arch=win32 ?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ @@ -702,8 +702,8 @@ @ cdecl -arch=win64 ?stossc at streambuf@@QEAAXXZ(ptr) msvcirt.?stossc at streambuf@@QEAAXXZ @ stub -arch=win32 ?str at istrstream@@QAEPADXZ @ stub -arch=win64 ?str at istrstream@@QEAAPEADXZ -@ stub -arch=win32 ?str at ostrstream@@QAEPADXZ -@ stub -arch=win64 ?str at ostrstream@@QEAAPEADXZ +@ thiscall -arch=win32 ?str at ostrstream@@QAEPADXZ(ptr) msvcirt.?str at ostrstream@@QAEPADXZ +@ cdecl -arch=win64 ?str at ostrstream@@QEAAPEADXZ(ptr) msvcirt.?str at ostrstream@@QEAAPEADXZ @ stub -arch=win32 ?str at strstream@@QAEPADXZ @ stub -arch=win64 ?str at strstream@@QEAAPEADXZ @ thiscall -arch=win32 ?str at strstreambuf@@QAEPADXZ(ptr) msvcirt.?str at strstreambuf@@QAEPADXZ diff --git a/dlls/msvcrt40/msvcrt40.spec b/dlls/msvcrt40/msvcrt40.spec index 07f3433..94293be 100644 --- a/dlls/msvcrt40/msvcrt40.spec +++ b/dlls/msvcrt40/msvcrt40.spec @@ -104,10 +104,10 @@ @ cdecl -arch=win64 ??0ostream_withassign@@QEAA at PEAVstreambuf@@@Z(ptr ptr long) msvcirt.??0ostream_withassign@@QEAA at PEAVstreambuf@@@Z @ thiscall -arch=win32 ??0ostream_withassign@@QAE at XZ(ptr long) msvcirt.??0ostream_withassign@@QAE at XZ @ cdecl -arch=win64 ??0ostream_withassign@@QEAA at XZ(ptr long) msvcirt.??0ostream_withassign@@QEAA at XZ -@ stub -arch=win32 ??0ostrstream@@QAE at ABV0@@Z -@ stub -arch=win64 ??0ostrstream@@QEAA at AEBV0@@Z -@ stub -arch=win32 ??0ostrstream@@QAE at PADHH@Z -@ stub -arch=win64 ??0ostrstream@@QEAA at PEADHH@Z +@ thiscall -arch=win32 ??0ostrstream@@QAE at ABV0@@Z(ptr ptr long) msvcirt.??0ostrstream@@QAE at ABV0@@Z +@ cdecl -arch=win64 ??0ostrstream@@QEAA at AEBV0@@Z(ptr ptr long) msvcirt.??0ostrstream@@QEAA at AEBV0@@Z +@ thiscall -arch=win32 ??0ostrstream@@QAE at PADHH@Z(ptr ptr long long long) msvcirt.??0ostrstream@@QAE at PADHH@Z +@ cdecl -arch=win64 ??0ostrstream@@QEAA at PEADHH@Z(ptr ptr long long long) msvcirt.??0ostrstream@@QEAA at PEADHH@Z @ thiscall -arch=win32 ??0ostrstream@@QAE at XZ(ptr long) msvcirt.??0ostrstream@@QAE at XZ @ cdecl -arch=win64 ??0ostrstream@@QEAA at XZ(ptr long) msvcirt.??0ostrstream@@QEAA at XZ @ thiscall -arch=win32 ??0stdiobuf@@QAE at ABV0@@Z(ptr ptr) msvcirt.??0stdiobuf@@QAE at ABV0@@Z @@ -240,8 +240,8 @@ @ cdecl -arch=win64 ??4ostream_withassign@@QEAAAEAVostream@@AEBV1@@Z(ptr ptr) msvcirt.??4ostream_withassign@@QEAAAEAVostream@@AEBV1@@Z @ thiscall -arch=win32 ??4ostream_withassign@@QAEAAVostream@@PAVstreambuf@@@Z(ptr ptr) msvcirt.??4ostream_withassign@@QAEAAVostream@@PAVstreambuf@@@Z @ cdecl -arch=win64 ??4ostream_withassign@@QEAAAEAVostream@@PEAVstreambuf@@@Z(ptr ptr) msvcirt.??4ostream_withassign@@QEAAAEAVostream@@PEAVstreambuf@@@Z -@ stub -arch=win32 ??4ostrstream@@QAEAAV0 at ABV0@@Z -@ stub -arch=win64 ??4ostrstream@@QEAAAEAV0 at AEBV0@@Z +@ thiscall -arch=win32 ??4ostrstream@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4ostrstream@@QAEAAV0 at ABV0@@Z +@ cdecl -arch=win64 ??4ostrstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4ostrstream@@QEAAAEAV0 at AEBV0@@Z @ thiscall -arch=win32 ??4stdiobuf@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4stdiobuf@@QAEAAV0 at ABV0@@Z @ cdecl -arch=win64 ??4stdiobuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4stdiobuf@@QEAAAEAV0 at AEBV0@@Z @ stub -arch=win32 ??4stdiostream@@QAEAAV0 at AAV0@@Z @@ -350,7 +350,7 @@ # @ extern ??_7ofstream@@6B@ @ extern ??_7ostream@@6B@ msvcirt.??_7ostream@@6B@ @ extern ??_7ostream_withassign@@6B@ msvcirt.??_7ostream_withassign@@6B@ -# @ extern ??_7ostrstream@@6B@ +@ extern ??_7ostrstream@@6B@ msvcirt.??_7ostrstream@@6B@ @ extern ??_7stdiobuf@@6B@ msvcirt.??_7stdiobuf@@6B@ # @ extern ??_7stdiostream@@6B@ @ extern ??_7streambuf@@6B@ msvcirt.??_7streambuf@@6B@ @@ -367,7 +367,7 @@ # @ extern ??_8ofstream@@7B@ @ extern ??_8ostream@@7B@ msvcirt.??_8ostream@@7B@ @ extern ??_8ostream_withassign@@7B@ msvcirt.??_8ostream_withassign@@7B@ -# @ extern ??_8ostrstream@@7B@ +@ extern ??_8ostrstream@@7B@ msvcirt.??_8ostrstream@@7B@ # @ extern ??_8stdiostream@@7Bistream@@@ # @ extern ??_8stdiostream@@7Bostream@@@ # @ extern ??_8strstream@@7Bistream@@@ @@ -390,8 +390,8 @@ @ cdecl -arch=win64 ??_Dostream@@QEAAXXZ(ptr) msvcirt.??_Dostream@@QEAAXXZ @ thiscall -arch=win32 ??_Dostream_withassign@@QAEXXZ(ptr) msvcirt.??_Dostream_withassign@@QAEXXZ @ cdecl -arch=win64 ??_Dostream_withassign@@QEAAXXZ(ptr) msvcirt.??_Dostream_withassign@@QEAAXXZ -@ stub -arch=win32 ??_Dostrstream@@QAEXXZ -@ stub -arch=win64 ??_Dostrstream@@QEAAXXZ +@ thiscall -arch=win32 ??_Dostrstream@@QAEXXZ(ptr) msvcirt.??_Dostrstream@@QAEXXZ +@ cdecl -arch=win64 ??_Dostrstream@@QEAAXXZ(ptr) msvcirt.??_Dostrstream@@QEAAXXZ @ stub -arch=win32 ??_Dstdiostream@@QAEXXZ @ stub -arch=win64 ??_Dstdiostream@@QEAAXXZ @ stub -arch=win32 ??_Dstrstream@@QAEXXZ @@ -413,7 +413,7 @@ @ stub -arch=win32 ??_Eofstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Eostream@@UAEPAXI at Z(ptr long) msvcirt.??_Eostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Eostream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Eostream_withassign@@UAEPAXI at Z -@ stub -arch=win32 ??_Eostrstream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Eostrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Eostrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estdiobuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estdiobuf@@UAEPAXI at Z @ stub -arch=win32 ??_Estdiostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estreambuf@@UAEPAXI at Z @@ -436,7 +436,7 @@ @ stub -arch=win32 ??_Gofstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gostream@@UAEPAXI at Z(ptr long) msvcirt.??_Gostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gostream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Gostream_withassign@@UAEPAXI at Z -@ stub -arch=win32 ??_Gostrstream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Gostrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gostrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstdiobuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstdiobuf@@UAEPAXI at Z @ stub -arch=win32 ??_Gstdiostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstreambuf@@UAEPAXI at Z @@ -646,8 +646,8 @@ @ cdecl -arch=win64 ?pbase at streambuf@@IEBAPEADXZ(ptr) msvcirt.?pbase at streambuf@@IEBAPEADXZ @ thiscall -arch=win32 ?pbump at streambuf@@IAEXH at Z(ptr long) msvcirt.?pbump at streambuf@@IAEXH at Z @ cdecl -arch=win64 ?pbump at streambuf@@IEAAXH at Z(ptr long) msvcirt.?pbump at streambuf@@IEAAXH at Z -@ stub -arch=win32 ?pcount at ostrstream@@QBEHXZ -@ stub -arch=win64 ?pcount at ostrstream@@QEBAHXZ +@ thiscall -arch=win32 ?pcount at ostrstream@@QBEHXZ(ptr) msvcirt.?pcount at ostrstream@@QBEHXZ +@ cdecl -arch=win64 ?pcount at ostrstream@@QEBAHXZ(ptr) msvcirt.?pcount at ostrstream@@QEBAHXZ @ stub -arch=win32 ?pcount at strstream@@QBEHXZ @ stub -arch=win64 ?pcount at strstream@@QEBAHXZ @ thiscall -arch=win32 ?peek at istream@@QAEHXZ(ptr) msvcirt.?peek at istream@@QAEHXZ @@ -680,8 +680,8 @@ @ stub -arch=win64 ?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ @ stub -arch=win32 ?rdbuf at ofstream@@QBEPAVfilebuf@@XZ @ stub -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ -@ stub -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ -@ stub -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ +@ thiscall -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ +@ cdecl -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ @ stub -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ @ stub -arch=win64 ?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ @ stub -arch=win32 ?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ @@ -774,8 +774,8 @@ @ cdecl -arch=win64 ?stossc at streambuf@@QEAAXXZ(ptr) msvcirt.?stossc at streambuf@@QEAAXXZ @ stub -arch=win32 ?str at istrstream@@QAEPADXZ @ stub -arch=win64 ?str at istrstream@@QEAAPEADXZ -@ stub -arch=win32 ?str at ostrstream@@QAEPADXZ -@ stub -arch=win64 ?str at ostrstream@@QEAAPEADXZ +@ thiscall -arch=win32 ?str at ostrstream@@QAEPADXZ(ptr) msvcirt.?str at ostrstream@@QAEPADXZ +@ cdecl -arch=win64 ?str at ostrstream@@QEAAPEADXZ(ptr) msvcirt.?str at ostrstream@@QEAAPEADXZ @ stub -arch=win32 ?str at strstream@@QAEPADXZ @ stub -arch=win64 ?str at strstream@@QEAAPEADXZ @ thiscall -arch=win32 ?str at strstreambuf@@QAEPADXZ(ptr) msvcirt.?str at strstreambuf@@QAEPADXZ -- 2.7.4 From madewokherd at gmail.com Wed Oct 19 10:03:05 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Wed, 19 Oct 2016 10:03:05 -0500 Subject: gdiplus: Reimplement GdipDrawPolygon based on GdipDrawPath. Message-ID: <1476889385-9250-1-git-send-email-madewokherd@gmail.com> From: Vincent Povirk Signed-off-by: Vincent Povirk --- dlls/gdiplus/graphics.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 324c06f..f9a6f3e 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -6164,8 +6164,8 @@ GpStatus WINGDIPAPI GdipSetClipRegion(GpGraphics *graphics, GpRegion *region, GpStatus WINGDIPAPI GdipDrawPolygon(GpGraphics *graphics,GpPen *pen,GDIPCONST GpPointF *points, INT count) { - INT save_state; - POINT *pti; + GpStatus status; + GpPath* path; TRACE("(%p, %p, %d)\n", graphics, points, count); @@ -6175,24 +6175,16 @@ GpStatus WINGDIPAPI GdipDrawPolygon(GpGraphics *graphics,GpPen *pen,GDIPCONST Gp if(graphics->busy) return ObjectBusy; - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } - - pti = heap_alloc_zero(sizeof(POINT) * count); - - save_state = prepare_dc(graphics, pen); - SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH)); + status = GdipCreatePath(FillModeAlternate, &path); + if (status != Ok) return status; - transform_and_round_points(graphics, pti, (GpPointF*)points, count); - Polygon(graphics->hdc, pti, count); + status = GdipAddPathPolygon(path, points, count); + if (status == Ok) + status = GdipDrawPath(graphics, pen, path); - restore_dc(graphics, save_state); - heap_free(pti); + GdipDeletePath(path); - return Ok; + return status; } GpStatus WINGDIPAPI GdipDrawPolygonI(GpGraphics *graphics,GpPen *pen,GDIPCONST GpPoint *points, -- 2.7.4 From huw at codeweavers.com Wed Oct 19 10:08:26 2016 From: huw at codeweavers.com (Huw Davies) Date: Wed, 19 Oct 2016 16:08:26 +0100 Subject: [PATCH 1/2] comctl32: Make the position variables signed to avoid wrapping in the HDF_RIGHT case. Message-ID: <1476889707-75429-1-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/comctl32/header.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/dlls/comctl32/header.c b/dlls/comctl32/header.c index edfe385..224ff9e 100644 --- a/dlls/comctl32/header.c +++ b/dlls/comctl32/header.c @@ -406,11 +406,12 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU /* Now text and image */ { - UINT rw, rh, /* width and height of r */ - *x = NULL, *w = NULL; /* x and width of the pic (bmp or img) which is part of cnt */ + INT rw, rh; /* width and height of r */ + INT *x = NULL; /* x and ... */ + UINT *w = NULL; /* ... width of the pic (bmp or img) which is part of cnt */ /* cnt,txt,img,bmp */ - UINT cx, tx, ix, bx, - cw, tw, iw, bw; + INT cx, tx, ix, bx; + UINT cw, tw, iw, bw; INT img_cx, img_cy; BITMAP bmp; @@ -501,14 +502,14 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU if (bw) { HDC hdcBitmap = CreateCompatibleDC (hClipDC); SelectObject (hdcBitmap, phdi->hbm); - BitBlt (hClipDC, bx, r.top + ((INT)rh - bmp.bmHeight) / 2, + BitBlt (hClipDC, bx, r.top + (rh - bmp.bmHeight) / 2, bmp.bmWidth, bmp.bmHeight, hdcBitmap, 0, 0, SRCCOPY); DeleteDC (hdcBitmap); } if (iw) { ImageList_DrawEx (infoPtr->himl, phdi->iImage, hClipDC, - ix, r.top + ((INT)rh - img_cy) / 2, + ix, r.top + (rh - img_cy) / 2, img_cx, img_cy, CLR_DEFAULT, CLR_DEFAULT, 0); } -- 2.8.2 From huw at codeweavers.com Wed Oct 19 10:08:27 2016 From: huw at codeweavers.com (Huw Davies) Date: Wed, 19 Oct 2016 16:08:27 +0100 Subject: [PATCH 2/2] comctl32: Add support for the sort arrows. Message-ID: <1476889707-75429-2-git-send-email-huw@codeweavers.com> Signed-off-by: Huw Davies --- dlls/comctl32/header.c | 98 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 79 insertions(+), 19 deletions(-) diff --git a/dlls/comctl32/header.c b/dlls/comctl32/header.c index 224ff9e..0206e3c 100644 --- a/dlls/comctl32/header.c +++ b/dlls/comctl32/header.c @@ -326,6 +326,48 @@ HEADER_DrawItemFrame(HEADER_INFO *infoPtr, HDC hdc, RECT *r, const HEADER_ITEM * } } +/* Create a region for the sort arrow with its bounding rect's top-left + co-ord x,y and its height h. */ +static HRGN create_sort_arrow( INT x, INT y, INT h, BOOL is_up ) +{ + char buffer[256]; + RGNDATA *data = (RGNDATA *)buffer; + DWORD size = FIELD_OFFSET(RGNDATA, Buffer[h * sizeof(RECT)]); + INT i, yinc = 1; + HRGN rgn; + + if (size > sizeof(buffer)) + { + data = HeapAlloc( GetProcessHeap(), 0, size ); + if (!data) return NULL; + } + data->rdh.dwSize = sizeof(data->rdh); + data->rdh.iType = RDH_RECTANGLES; + data->rdh.nCount = 0; + data->rdh.nRgnSize = h * sizeof(RECT); + + if (!is_up) + { + y += h - 1; + yinc = -1; + } + + x += h - 1; /* set x to the centre */ + + for (i = 0; i < h; i++, y += yinc) + { + RECT *rect = (RECT *)data->Buffer + data->rdh.nCount; + rect->left = x - i; + rect->top = y; + rect->right = x + i + 1; + rect->bottom = y + 1; + data->rdh.nCount++; + } + rgn = ExtCreateRegion( NULL, size, data ); + if (data != (RGNDATA *)buffer) HeapFree( GetProcessHeap(), 0, data ); + return rgn; +} + static INT HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESULT lCDFlags) { @@ -413,10 +455,11 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU INT cx, tx, ix, bx; UINT cw, tw, iw, bw; INT img_cx, img_cy; + INT sort_w, sort_x, sort_h; BITMAP bmp; HEADER_PrepareCallbackItems(infoPtr, iItem, HDI_TEXT|HDI_IMAGE); - cw = iw = bw = 0; + cw = iw = bw = sort_w = 0; rw = r.right - r.left; rh = r.bottom - r.top; @@ -435,23 +478,28 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU cw = textRect.right - textRect.left + 2 * infoPtr->iMargin; } - if ((phdi->fmt & HDF_IMAGE) && ImageList_GetIconSize( infoPtr->himl, &img_cx, &img_cy )) { - iw = img_cx + 2 * infoPtr->iMargin; - x = &ix; - w = &iw; - } - - if ((phdi->fmt & HDF_BITMAP) && (phdi->hbm)) { - GetObjectW (phdi->hbm, sizeof(BITMAP), &bmp); - bw = bmp.bmWidth + 2 * infoPtr->iMargin; - if (!iw) { - x = &bx; - w = &bw; - } - } + if (phdi->fmt & (HDF_SORTUP | HDF_SORTDOWN)) { + sort_h = MulDiv( infoPtr->nHeight - VERT_BORDER, 4, 13 ); + sort_w = 2 * sort_h - 1 + infoPtr->iMargin * 2; + cw += sort_w; + } else { /* sort arrows take precedent over images/bitmaps */ + if ((phdi->fmt & HDF_IMAGE) && ImageList_GetIconSize( infoPtr->himl, &img_cx, &img_cy )) { + iw = img_cx + 2 * infoPtr->iMargin; + x = &ix; + w = &iw; + } - if (bw || iw) - cw += *w; + if ((phdi->fmt & HDF_BITMAP) && (phdi->hbm)) { + GetObjectW (phdi->hbm, sizeof(BITMAP), &bmp); + bw = bmp.bmWidth + 2 * infoPtr->iMargin; + if (!iw) { + x = &bx; + w = &bw; + } + } + if (bw || iw) + cw += *w; + } /* align cx using the unclipped cw */ if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_LEFT) @@ -470,7 +518,10 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU tx = cx + infoPtr->iMargin; /* since cw might have changed we have to recalculate tw */ tw = cw - infoPtr->iMargin * 2; - + + tw -= sort_w; + sort_x = cx + tw + infoPtr->iMargin * 3; + if (iw || bw) { tw -= *w; if (phdi->fmt & HDF_BITMAP_ON_RIGHT) { @@ -494,11 +545,20 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU bx = cx + cw + infoPtr->iMargin; } - if (iw || bw) { + if (sort_w || iw || bw) { HDC hClipDC = GetDC(infoPtr->hwndSelf); HRGN hClipRgn = CreateRectRgn(r.left, r.top, r.right, r.bottom); SelectClipRgn(hClipDC, hClipRgn); + if (sort_w) { + HRGN arrow = create_sort_arrow( sort_x, r.top + (rh - sort_h) / 2, + sort_h, phdi->fmt & HDF_SORTUP ); + if (arrow) { + FillRgn( hClipDC, arrow, GetSysColorBrush( COLOR_GRAYTEXT ) ); + DeleteObject( arrow ); + } + } + if (bw) { HDC hdcBitmap = CreateCompatibleDC (hClipDC); SelectObject (hdcBitmap, phdi->hbm); -- 2.8.2 From nsivov at codeweavers.com Wed Oct 19 12:00:21 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Wed, 19 Oct 2016 20:00:21 +0300 Subject: [v2 PATCH] d2d1: Initial implementation of bitmap render target Message-ID: <20161019170021.19572-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- v2: simplified initialization logic dlls/d2d1/Makefile.in | 1 + dlls/d2d1/bitmap_render_target.c | 832 +++++++++++++++++++++++++++++++++++++++ dlls/d2d1/brush.c | 4 +- dlls/d2d1/d2d1_private.h | 18 +- dlls/d2d1/render_target.c | 68 ++-- dlls/d2d1/tests/d2d1.c | 13 +- 6 files changed, 895 insertions(+), 41 deletions(-) create mode 100644 dlls/d2d1/bitmap_render_target.c diff --git a/dlls/d2d1/Makefile.in b/dlls/d2d1/Makefile.in index deacd7a..68e9268 100644 --- a/dlls/d2d1/Makefile.in +++ b/dlls/d2d1/Makefile.in @@ -5,6 +5,7 @@ DELAYIMPORTS = dwrite C_SRCS = \ bitmap.c \ + bitmap_render_target.c \ brush.c \ dc_render_target.c \ factory.c \ diff --git a/dlls/d2d1/bitmap_render_target.c b/dlls/d2d1/bitmap_render_target.c new file mode 100644 index 0000000..67b0713 --- /dev/null +++ b/dlls/d2d1/bitmap_render_target.c @@ -0,0 +1,832 @@ +/* + * Copyright 2014 Henri Verbeet for CodeWeavers + * Copyright 2016 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include "d2d1_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d2d); + +static inline struct d2d_bitmap_render_target *impl_from_ID2D1BitmapRenderTarget(ID2D1BitmapRenderTarget *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_bitmap_render_target, ID2D1BitmapRenderTarget_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_QueryInterface(ID2D1BitmapRenderTarget *iface, + REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1BitmapRenderTarget) + || IsEqualGUID(iid, &IID_ID2D1RenderTarget) + || IsEqualGUID(iid, &IID_ID2D1Resource) + || IsEqualGUID(iid, &IID_IUnknown)) + { + ID2D1BitmapRenderTarget_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_bitmap_render_target_AddRef(ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + ULONG refcount = InterlockedIncrement(&render_target->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_bitmap_render_target_Release(ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + ULONG refcount = InterlockedDecrement(&render_target->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (!refcount) + { + ID2D1RenderTarget_Release(render_target->dxgi_target); + ID2D1Bitmap_Release(render_target->bitmap); + HeapFree(GetProcessHeap(), 0, render_target); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_GetFactory(ID2D1BitmapRenderTarget *iface, + ID2D1Factory **factory) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, factory %p.\n", iface, factory); + + ID2D1RenderTarget_GetFactory(render_target->dxgi_target, factory); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateBitmap(ID2D1BitmapRenderTarget *iface, + D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, size {%u, %u}, src_data %p, pitch %u, desc %p, bitmap %p.\n", + iface, size.width, size.height, src_data, pitch, desc, bitmap); + + return ID2D1RenderTarget_CreateBitmap(render_target->dxgi_target, size, src_data, pitch, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateBitmapFromWicBitmap(ID2D1BitmapRenderTarget *iface, + IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, bitmap_source %p, desc %p, bitmap %p.\n", + iface, bitmap_source, desc, bitmap); + + return ID2D1RenderTarget_CreateBitmapFromWicBitmap(render_target->dxgi_target, bitmap_source, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateSharedBitmap(ID2D1BitmapRenderTarget *iface, + REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, iid %s, data %p, desc %p, bitmap %p.\n", + iface, debugstr_guid(iid), data, desc, bitmap); + + return ID2D1RenderTarget_CreateSharedBitmap(render_target->dxgi_target, iid, data, desc, bitmap); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateBitmapBrush(ID2D1BitmapRenderTarget *iface, + ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc, + const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1BitmapBrush **brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p.\n", + iface, bitmap, bitmap_brush_desc, brush_desc, brush); + + return ID2D1RenderTarget_CreateBitmapBrush(render_target->dxgi_target, + bitmap, bitmap_brush_desc, brush_desc, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateSolidColorBrush(ID2D1BitmapRenderTarget *iface, + const D2D1_COLOR_F *color, const D2D1_BRUSH_PROPERTIES *desc, ID2D1SolidColorBrush **brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, color %p, desc %p, brush %p.\n", iface, color, desc, brush); + + return ID2D1RenderTarget_CreateSolidColorBrush(render_target->dxgi_target, color, desc, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateGradientStopCollection(ID2D1BitmapRenderTarget *iface, + const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode, + ID2D1GradientStopCollection **gradient) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n", + iface, stops, stop_count, gamma, extend_mode, gradient); + + return ID2D1RenderTarget_CreateGradientStopCollection(render_target->dxgi_target, + stops, stop_count, gamma, extend_mode, gradient); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateLinearGradientBrush(ID2D1BitmapRenderTarget *iface, + const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1GradientStopCollection *gradient, ID2D1LinearGradientBrush **brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n", + iface, gradient_brush_desc, brush_desc, gradient, brush); + + return ID2D1RenderTarget_CreateLinearGradientBrush(render_target->dxgi_target, + gradient_brush_desc, brush_desc, gradient, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateRadialGradientBrush(ID2D1BitmapRenderTarget *iface, + const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1GradientStopCollection *gradient, ID2D1RadialGradientBrush **brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n", + iface, gradient_brush_desc, brush_desc, gradient, brush); + + return ID2D1RenderTarget_CreateRadialGradientBrush(render_target->dxgi_target, + gradient_brush_desc, brush_desc, gradient, brush); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateCompatibleRenderTarget(ID2D1BitmapRenderTarget *iface, + const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **render_target) +{ + struct d2d_bitmap_render_target *rt = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p,\n", + iface, size, pixel_size, format, options, render_target); + + return ID2D1RenderTarget_CreateCompatibleRenderTarget(rt->dxgi_target, + size, pixel_size, format, options, render_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateLayer(ID2D1BitmapRenderTarget *iface, + const D2D1_SIZE_F *size, ID2D1Layer **layer) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, size %p, layer %p.\n", iface, size, layer); + + return ID2D1RenderTarget_CreateLayer(render_target->dxgi_target, size, layer); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_CreateMesh(ID2D1BitmapRenderTarget *iface, ID2D1Mesh **mesh) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, mesh %p.\n", iface, mesh); + + return ID2D1RenderTarget_CreateMesh(render_target->dxgi_target, mesh); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawLine(ID2D1BitmapRenderTarget *iface, + D2D1_POINT_2F p0, D2D1_POINT_2F p1, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, p0 {%.8e, %.8e}, p1 {%.8e, %.8e}, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, p0.x, p0.y, p1.x, p1.y, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawLine(render_target->dxgi_target, p0, p1, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawRectangle(ID2D1BitmapRenderTarget *iface, + const D2D1_RECT_F *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, rect, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawRectangle(render_target->dxgi_target, rect, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_FillRectangle(ID2D1BitmapRenderTarget *iface, + const D2D1_RECT_F *rect, ID2D1Brush *brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p.\n", iface, rect, brush); + + ID2D1RenderTarget_FillRectangle(render_target->dxgi_target, rect, brush); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawRoundedRectangle(ID2D1BitmapRenderTarget *iface, + const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, rect, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawRoundedRectangle(render_target->dxgi_target, rect, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_FillRoundedRectangle(ID2D1BitmapRenderTarget *iface, + const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, rect %p, brush %p.\n", iface, rect, brush); + + ID2D1RenderTarget_FillRoundedRectangle(render_target->dxgi_target, rect, brush); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawEllipse(ID2D1BitmapRenderTarget *iface, + const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, ellipse %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, ellipse, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawEllipse(render_target->dxgi_target, ellipse, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_FillEllipse(ID2D1BitmapRenderTarget *iface, + const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, ellipse %p, brush %p.\n", iface, ellipse, brush); + + ID2D1RenderTarget_FillEllipse(render_target->dxgi_target, ellipse, brush); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawGeometry(ID2D1BitmapRenderTarget *iface, + ID2D1Geometry *geometry, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, geometry %p, brush %p, stroke_width %.8e, stroke_style %p.\n", + iface, geometry, brush, stroke_width, stroke_style); + + ID2D1RenderTarget_DrawGeometry(render_target->dxgi_target, geometry, brush, stroke_width, stroke_style); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_FillGeometry(ID2D1BitmapRenderTarget *iface, + ID2D1Geometry *geometry, ID2D1Brush *brush, ID2D1Brush *opacity_brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, geometry %p, brush %p, opacity_brush %p.\n", iface, geometry, brush, opacity_brush); + + ID2D1RenderTarget_FillGeometry(render_target->dxgi_target, geometry, brush, opacity_brush); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_FillMesh(ID2D1BitmapRenderTarget *iface, + ID2D1Mesh *mesh, ID2D1Brush *brush) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, mesh %p, brush %p.\n", iface, mesh, brush); + + ID2D1RenderTarget_FillMesh(render_target->dxgi_target, mesh, brush); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_FillOpacityMask(ID2D1BitmapRenderTarget *iface, + ID2D1Bitmap *mask, ID2D1Brush *brush, D2D1_OPACITY_MASK_CONTENT content, + const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, mask %p, brush %p, content %#x, dst_rect %p, src_rect %p.\n", + iface, mask, brush, content, dst_rect, src_rect); + + ID2D1RenderTarget_FillOpacityMask(render_target->dxgi_target, + mask, brush, content, dst_rect, src_rect); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawBitmap(ID2D1BitmapRenderTarget *iface, + ID2D1Bitmap *bitmap, const D2D1_RECT_F *dst_rect, float opacity, + D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, const D2D1_RECT_F *src_rect) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, bitmap %p, dst_rect %p, opacity %.8e, interpolation_mode %#x, src_rect %p.\n", + iface, bitmap, dst_rect, opacity, interpolation_mode, src_rect); + + ID2D1RenderTarget_DrawBitmap(render_target->dxgi_target, + bitmap, dst_rect, opacity, interpolation_mode, src_rect); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawText(ID2D1BitmapRenderTarget *iface, + const WCHAR *string, UINT32 string_len, IDWriteTextFormat *text_format, const D2D1_RECT_F *layout_rect, + ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuring_mode) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, string %s, string_len %u, text_format %p, layout_rect %p, " + "brush %p, options %#x, measuring_mode %#x.\n", + iface, debugstr_wn(string, string_len), string_len, text_format, layout_rect, + brush, options, measuring_mode); + + ID2D1RenderTarget_DrawText(render_target->dxgi_target, string, string_len, + text_format, layout_rect, brush, options, measuring_mode); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawTextLayout(ID2D1BitmapRenderTarget *iface, + D2D1_POINT_2F origin, IDWriteTextLayout *layout, ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, origin {%.8e, %.8e}, layout %p, brush %p, options %#x.\n", + iface, origin.x, origin.y, layout, brush, options); + + ID2D1RenderTarget_DrawTextLayout(render_target->dxgi_target, origin, layout, brush, options); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_DrawGlyphRun(ID2D1BitmapRenderTarget *iface, + D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush, + DWRITE_MEASURING_MODE measuring_mode) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, baseline_origin {%.8e, %.8e}, glyph_run %p, brush %p, measuring_mode %#x.\n", + iface, baseline_origin.x, baseline_origin.y, glyph_run, brush, measuring_mode); + + ID2D1RenderTarget_DrawGlyphRun(render_target->dxgi_target, + baseline_origin, glyph_run, brush, measuring_mode); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_SetTransform(ID2D1BitmapRenderTarget *iface, + const D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, transform %p.\n", iface, transform); + + ID2D1RenderTarget_SetTransform(render_target->dxgi_target, transform); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_GetTransform(ID2D1BitmapRenderTarget *iface, + D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, transform %p.\n", iface, transform); + + ID2D1RenderTarget_GetTransform(render_target->dxgi_target, transform); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_SetAntialiasMode(ID2D1BitmapRenderTarget *iface, + D2D1_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, antialias_mode %#x.\n", iface, antialias_mode); + + ID2D1RenderTarget_SetAntialiasMode(render_target->dxgi_target, antialias_mode); +} + +static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_bitmap_render_target_GetAntialiasMode(ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetAntialiasMode(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_SetTextAntialiasMode(ID2D1BitmapRenderTarget *iface, + D2D1_TEXT_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, antialias_mode %#x.\n", iface, antialias_mode); + + ID2D1RenderTarget_SetTextAntialiasMode(render_target->dxgi_target, antialias_mode); +} + +static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_bitmap_render_target_GetTextAntialiasMode( + ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetTextAntialiasMode(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_SetTextRenderingParams(ID2D1BitmapRenderTarget *iface, + IDWriteRenderingParams *text_rendering_params) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params); + + ID2D1RenderTarget_SetTextRenderingParams(render_target->dxgi_target, text_rendering_params); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_GetTextRenderingParams(ID2D1BitmapRenderTarget *iface, + IDWriteRenderingParams **text_rendering_params) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params); + + ID2D1RenderTarget_GetTextRenderingParams(render_target->dxgi_target, text_rendering_params); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_SetTags(ID2D1BitmapRenderTarget *iface, D2D1_TAG tag1, + D2D1_TAG tag2) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, tag1 %s, tag2 %s.\n", iface, wine_dbgstr_longlong(tag1), wine_dbgstr_longlong(tag2)); + + ID2D1RenderTarget_SetTags(render_target->dxgi_target, tag1, tag2); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_GetTags(ID2D1BitmapRenderTarget *iface, D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + ID2D1RenderTarget_GetTags(render_target->dxgi_target, tag1, tag2); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_PushLayer(ID2D1BitmapRenderTarget *iface, + const D2D1_LAYER_PARAMETERS *layer_parameters, ID2D1Layer *layer) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, layer_parameters %p, layer %p.\n", iface, layer_parameters, layer); + + ID2D1RenderTarget_PushLayer(render_target->dxgi_target, layer_parameters, layer); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_PopLayer(ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_PopLayer(render_target->dxgi_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_Flush(ID2D1BitmapRenderTarget *iface, D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + return ID2D1RenderTarget_Flush(render_target->dxgi_target, tag1, tag2); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_SaveDrawingState(ID2D1BitmapRenderTarget *iface, + ID2D1DrawingStateBlock *state_block) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, state_block %p.\n", iface, state_block); + + ID2D1RenderTarget_SaveDrawingState(render_target->dxgi_target, state_block); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_RestoreDrawingState(ID2D1BitmapRenderTarget *iface, + ID2D1DrawingStateBlock *state_block) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, state_block %p.\n", iface, state_block); + + ID2D1RenderTarget_RestoreDrawingState(render_target->dxgi_target, state_block); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_PushAxisAlignedClip(ID2D1BitmapRenderTarget *iface, + const D2D1_RECT_F *clip_rect, D2D1_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, clip_rect %p, antialias_mode %#x.\n", iface, clip_rect, antialias_mode); + + ID2D1RenderTarget_PushAxisAlignedClip(render_target->dxgi_target, clip_rect, antialias_mode); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_PopAxisAlignedClip(ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_PopAxisAlignedClip(render_target->dxgi_target); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_Clear(ID2D1BitmapRenderTarget *iface, const D2D1_COLOR_F *color) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, color %p.\n", iface, color); + + ID2D1RenderTarget_Clear(render_target->dxgi_target, color); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_BeginDraw(ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + ID2D1RenderTarget_BeginDraw(render_target->dxgi_target); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_EndDraw(ID2D1BitmapRenderTarget *iface, + D2D1_TAG *tag1, D2D1_TAG *tag2) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2); + + return ID2D1RenderTarget_EndDraw(render_target->dxgi_target, tag1, tag2); +} + +static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_bitmap_render_target_GetPixelFormat(ID2D1BitmapRenderTarget *iface, + D2D1_PIXEL_FORMAT *format) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, format %p.\n", iface, format); + + *format = ID2D1RenderTarget_GetPixelFormat(render_target->dxgi_target); + return format; +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_SetDpi(ID2D1BitmapRenderTarget *iface, float dpi_x, float dpi_y) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, dpi_x %.8e, dpi_y %.8e.\n", iface, dpi_x, dpi_y); + + ID2D1RenderTarget_SetDpi(render_target->dxgi_target, dpi_x, dpi_y); +} + +static void STDMETHODCALLTYPE d2d_bitmap_render_target_GetDpi(ID2D1BitmapRenderTarget *iface, + float *dpi_x, float *dpi_y) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y); + + ID2D1RenderTarget_GetDpi(render_target->dxgi_target, dpi_x, dpi_y); +} + +static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_bitmap_render_target_GetSize(ID2D1BitmapRenderTarget *iface, + D2D1_SIZE_F *size) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, size %p.\n", iface, size); + + *size = ID2D1RenderTarget_GetSize(render_target->dxgi_target); + return size; +} + +static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_bitmap_render_target_GetPixelSize(ID2D1BitmapRenderTarget *iface, + D2D1_SIZE_U *pixel_size) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, pixel_size %p.\n", iface, pixel_size); + + *pixel_size = ID2D1RenderTarget_GetPixelSize(render_target->dxgi_target); + return pixel_size; +} + +static UINT32 STDMETHODCALLTYPE d2d_bitmap_render_target_GetMaximumBitmapSize(ID2D1BitmapRenderTarget *iface) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p.\n", iface); + + return ID2D1RenderTarget_GetMaximumBitmapSize(render_target->dxgi_target); +} + +static BOOL STDMETHODCALLTYPE d2d_bitmap_render_target_IsSupported(ID2D1BitmapRenderTarget *iface, + const D2D1_RENDER_TARGET_PROPERTIES *desc) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + return ID2D1RenderTarget_IsSupported(render_target->dxgi_target, desc); +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_GetBitmap(ID2D1BitmapRenderTarget *iface, + ID2D1Bitmap **bitmap) +{ + struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface); + + TRACE("iface %p, bitmap %p.\n", iface, bitmap); + + ID2D1Bitmap_AddRef(*bitmap = render_target->bitmap); + return S_OK; +} + +static const struct ID2D1BitmapRenderTargetVtbl d2d_bitmap_render_target_vtbl = +{ + d2d_bitmap_render_target_QueryInterface, + d2d_bitmap_render_target_AddRef, + d2d_bitmap_render_target_Release, + d2d_bitmap_render_target_GetFactory, + d2d_bitmap_render_target_CreateBitmap, + d2d_bitmap_render_target_CreateBitmapFromWicBitmap, + d2d_bitmap_render_target_CreateSharedBitmap, + d2d_bitmap_render_target_CreateBitmapBrush, + d2d_bitmap_render_target_CreateSolidColorBrush, + d2d_bitmap_render_target_CreateGradientStopCollection, + d2d_bitmap_render_target_CreateLinearGradientBrush, + d2d_bitmap_render_target_CreateRadialGradientBrush, + d2d_bitmap_render_target_CreateCompatibleRenderTarget, + d2d_bitmap_render_target_CreateLayer, + d2d_bitmap_render_target_CreateMesh, + d2d_bitmap_render_target_DrawLine, + d2d_bitmap_render_target_DrawRectangle, + d2d_bitmap_render_target_FillRectangle, + d2d_bitmap_render_target_DrawRoundedRectangle, + d2d_bitmap_render_target_FillRoundedRectangle, + d2d_bitmap_render_target_DrawEllipse, + d2d_bitmap_render_target_FillEllipse, + d2d_bitmap_render_target_DrawGeometry, + d2d_bitmap_render_target_FillGeometry, + d2d_bitmap_render_target_FillMesh, + d2d_bitmap_render_target_FillOpacityMask, + d2d_bitmap_render_target_DrawBitmap, + d2d_bitmap_render_target_DrawText, + d2d_bitmap_render_target_DrawTextLayout, + d2d_bitmap_render_target_DrawGlyphRun, + d2d_bitmap_render_target_SetTransform, + d2d_bitmap_render_target_GetTransform, + d2d_bitmap_render_target_SetAntialiasMode, + d2d_bitmap_render_target_GetAntialiasMode, + d2d_bitmap_render_target_SetTextAntialiasMode, + d2d_bitmap_render_target_GetTextAntialiasMode, + d2d_bitmap_render_target_SetTextRenderingParams, + d2d_bitmap_render_target_GetTextRenderingParams, + d2d_bitmap_render_target_SetTags, + d2d_bitmap_render_target_GetTags, + d2d_bitmap_render_target_PushLayer, + d2d_bitmap_render_target_PopLayer, + d2d_bitmap_render_target_Flush, + d2d_bitmap_render_target_SaveDrawingState, + d2d_bitmap_render_target_RestoreDrawingState, + d2d_bitmap_render_target_PushAxisAlignedClip, + d2d_bitmap_render_target_PopAxisAlignedClip, + d2d_bitmap_render_target_Clear, + d2d_bitmap_render_target_BeginDraw, + d2d_bitmap_render_target_EndDraw, + d2d_bitmap_render_target_GetPixelFormat, + d2d_bitmap_render_target_SetDpi, + d2d_bitmap_render_target_GetDpi, + d2d_bitmap_render_target_GetSize, + d2d_bitmap_render_target_GetPixelSize, + d2d_bitmap_render_target_GetMaximumBitmapSize, + d2d_bitmap_render_target_IsSupported, + d2d_bitmap_render_target_GetBitmap +}; + +HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_target, + const struct d2d_d3d_render_target *parent_target, const D2D1_SIZE_F *size, + const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *pixel_format, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options) +{ + D2D1_RENDER_TARGET_PROPERTIES dxgi_rt_desc; + D2D1_BITMAP_PROPERTIES bitmap_desc; + D3D10_TEXTURE2D_DESC texture_desc; + IDXGISurface *dxgi_surface; + ID3D10Texture2D *texture; + HRESULT hr; + + if (options) + FIXME("Compatible target options are ignored, %#x.\n", options); + + render_target->ID2D1BitmapRenderTarget_iface.lpVtbl = &d2d_bitmap_render_target_vtbl; + render_target->refcount = 1; + + dxgi_rt_desc.type = parent_target->desc.type; + dxgi_rt_desc.usage = parent_target->desc.usage; + dxgi_rt_desc.minLevel = parent_target->desc.minLevel; + + if (pixel_size) + { + texture_desc.Width = pixel_size->width; + texture_desc.Height = pixel_size->height; + } + else if (size) + { + texture_desc.Width = ceilf((size->width * parent_target->desc.dpiX) / 96.0f); + texture_desc.Height = ceilf((size->height * parent_target->desc.dpiY) / 96.0f); + } + else + { + texture_desc.Width = parent_target->pixel_size.width; + texture_desc.Height = parent_target->pixel_size.height; + } + + if (size) + { + dxgi_rt_desc.dpiX = (texture_desc.Width * 96.0f) / size->width; + dxgi_rt_desc.dpiY = (texture_desc.Height * 96.0f) / size->height; + } + else + { + dxgi_rt_desc.dpiX = parent_target->desc.dpiX; + dxgi_rt_desc.dpiY = parent_target->desc.dpiY; + } + + if (!pixel_format || pixel_format->format == DXGI_FORMAT_UNKNOWN) + texture_desc.Format = parent_target->desc.pixelFormat.format; + else + texture_desc.Format = pixel_format->format; + dxgi_rt_desc.pixelFormat.format = texture_desc.Format; + + if (!pixel_format || pixel_format->alphaMode == D2D1_ALPHA_MODE_UNKNOWN) + dxgi_rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + else + dxgi_rt_desc.pixelFormat.alphaMode = pixel_format->alphaMode; + + texture_desc.MipLevels = 1; + texture_desc.ArraySize = 1; + texture_desc.SampleDesc.Count = 1; + texture_desc.SampleDesc.Quality = 0; + texture_desc.Usage = D3D10_USAGE_DEFAULT; + texture_desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE; + texture_desc.CPUAccessFlags = 0; + texture_desc.MiscFlags = 0; + + if (FAILED(hr = ID3D10Device_CreateTexture2D(parent_target->device, &texture_desc, NULL, &texture))) + { + WARN("Failed to create texture, hr %#x.\n", hr); + return hr; + } + + hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&dxgi_surface); + ID3D10Texture2D_Release(texture); + if (FAILED(hr)) + { + WARN("Failed to get DXGI surface interface, hr %#x.\n", hr); + return hr; + } + + if (FAILED(hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(parent_target->factory, dxgi_surface, &dxgi_rt_desc, + &render_target->dxgi_target))) + { + WARN("Failed to create DXGI surface render target, hr %#x.\n", hr); + IDXGISurface_Release(dxgi_surface); + return hr; + } + + bitmap_desc.pixelFormat = dxgi_rt_desc.pixelFormat; + bitmap_desc.dpiX = dxgi_rt_desc.dpiX; + bitmap_desc.dpiY = dxgi_rt_desc.dpiY; + + hr = ID2D1RenderTarget_CreateSharedBitmap(render_target->dxgi_target, &IID_IDXGISurface, dxgi_surface, + &bitmap_desc, &render_target->bitmap); + IDXGISurface_Release(dxgi_surface); + if (FAILED(hr)) + { + WARN("Failed to create shared bitmap, hr %#x.\n", hr); + ID2D1RenderTarget_Release(render_target->dxgi_target); + return hr; + } + + return S_OK; +} diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c index 1454faf..38872ea 100644 --- a/dlls/d2d1/brush.c +++ b/dlls/d2d1/brush.c @@ -789,11 +789,11 @@ static BOOL d2d_brush_fill_cb(struct d2d_brush *brush, struct d2d_d3d_render_tar /* Scale for dpi. */ w = render_target->drawing_state.transform; - dpi_scale = render_target->dpi_x / 96.0f; + dpi_scale = render_target->desc.dpiX / 96.0f; w._11 *= dpi_scale; w._21 *= dpi_scale; w._31 *= dpi_scale; - dpi_scale = render_target->dpi_y / 96.0f; + dpi_scale = render_target->desc.dpiY / 96.0f; w._12 *= dpi_scale; w._22 *= dpi_scale; w._32 *= dpi_scale; diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index c5c3a03..b49fce4 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -87,11 +87,9 @@ struct d2d_d3d_render_target IDWriteRenderingParams *text_rendering_params; IDWriteRenderingParams *default_text_rendering_params; - D2D1_PIXEL_FORMAT format; + D2D1_RENDER_TARGET_PROPERTIES desc; D2D1_SIZE_U pixel_size; struct d2d_clip_stack clip_stack; - float dpi_x; - float dpi_y; }; HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory, @@ -146,6 +144,20 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc, const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_desc) DECLSPEC_HIDDEN; +struct d2d_bitmap_render_target +{ + ID2D1BitmapRenderTarget ID2D1BitmapRenderTarget_iface; + LONG refcount; + + ID2D1RenderTarget *dxgi_target; + ID2D1Bitmap *bitmap; +}; + +HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_target, + const struct d2d_d3d_render_target *parent_target, const D2D1_SIZE_F *size, + const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options) DECLSPEC_HIDDEN; + struct d2d_gradient { ID2D1GradientStopCollection ID2D1GradientStopCollection_iface; diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index 4417b85..bc31f4d 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -426,12 +426,30 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateRadialGradientBrush static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateCompatibleRenderTarget(ID2D1RenderTarget *iface, const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format, - D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **render_target) + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **rt) { - FIXME("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p stub!\n", - iface, size, pixel_size, format, options, render_target); + struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface); + struct d2d_bitmap_render_target *object; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p.\n", + iface, size, pixel_size, format, options, rt); + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d2d_bitmap_render_target_init(object, render_target, size, pixel_size, + format, options))) + { + WARN("Failed to initialize render target, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + TRACE("Created render target %p.\n", object); + *rt = &object->ID2D1BitmapRenderTarget_iface; + + return S_OK; } static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateLayer(ID2D1RenderTarget *iface, @@ -602,8 +620,8 @@ static void d2d_rt_fill_geometry(struct d2d_d3d_render_target *render_target, float _12, _22, _32, pad1; } transform; - tmp_x = (2.0f * render_target->dpi_x) / (96.0f * render_target->pixel_size.width); - tmp_y = -(2.0f * render_target->dpi_y) / (96.0f * render_target->pixel_size.height); + tmp_x = (2.0f * render_target->desc.dpiX) / (96.0f * render_target->pixel_size.width); + tmp_y = -(2.0f * render_target->desc.dpiY) / (96.0f * render_target->pixel_size.height); w = render_target->drawing_state.transform; w._11 *= tmp_x; w._21 *= tmp_x; @@ -826,7 +844,7 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawText(ID2D1RenderTarget * layout_rect->right - layout_rect->left, layout_rect->bottom - layout_rect->top, &text_layout); else hr = IDWriteFactory_CreateGdiCompatibleTextLayout(dwrite_factory, string, string_len, text_format, - layout_rect->right - layout_rect->left, layout_rect->bottom - layout_rect->top, render_target->dpi_x / 96.0f, + layout_rect->right - layout_rect->left, layout_rect->bottom - layout_rect->top, render_target->desc.dpiX / 96.0f, (DWRITE_MATRIX*)&render_target->drawing_state.transform, measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL, &text_layout); IDWriteFactory_Release(dwrite_factory); if (FAILED(hr)) @@ -975,10 +993,10 @@ static void d2d_rt_draw_glyph_run_bitmap(struct d2d_d3d_render_target *render_ta bitmap_desc.pixelFormat.format = DXGI_FORMAT_A8_UNORM; bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; - bitmap_desc.dpiX = render_target->dpi_x; + bitmap_desc.dpiX = render_target->desc.dpiX; if (texture_type == DWRITE_TEXTURE_CLEARTYPE_3x1) bitmap_desc.dpiX *= 3.0f; - bitmap_desc.dpiY = render_target->dpi_y; + bitmap_desc.dpiY = render_target->desc.dpiY; if (FAILED(hr = d2d_d3d_render_target_CreateBitmap(&render_target->ID2D1RenderTarget_iface, bitmap_size, opacity_values, bitmap_size.width, &bitmap_desc, &opacity_bitmap))) { @@ -1040,7 +1058,7 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGlyphRun(ID2D1RenderTarg if (render_target->drawing_state.textAntialiasMode != D2D1_TEXT_ANTIALIAS_MODE_DEFAULT) FIXME("Ignoring text antialiasing mode %#x.\n", render_target->drawing_state.textAntialiasMode); - ppd = max(render_target->dpi_x, render_target->dpi_y) / 96.0f; + ppd = max(render_target->desc.dpiX, render_target->desc.dpiY) / 96.0f; rendering_params = render_target->text_rendering_params ? render_target->text_rendering_params : render_target->default_text_rendering_params; if (FAILED(hr = IDWriteFontFace_GetRecommendedRenderingMode(glyph_run->fontFace, glyph_run->fontEmSize, @@ -1223,8 +1241,8 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_PushAxisAlignedClip(ID2D1Ren if (antialias_mode != D2D1_ANTIALIAS_MODE_ALIASED) FIXME("Ignoring antialias_mode %#x.\n", antialias_mode); - x_scale = render_target->dpi_x / 96.0f; - y_scale = render_target->dpi_y / 96.0f; + x_scale = render_target->desc.dpiX / 96.0f; + y_scale = render_target->desc.dpiY / 96.0f; d2d_point_transform(&point, &render_target->drawing_state.transform, clip_rect->left * x_scale, clip_rect->top * y_scale); d2d_rect_set(&transformed_rect, point.x, point.y, point.x, point.y); @@ -1286,7 +1304,7 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *ifa if (color) c = *color; - if (render_target->format.alphaMode == D2D1_ALPHA_MODE_IGNORE) + if (render_target->desc.pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE) c.a = 1.0f; c.r *= c.a; c.g *= c.a; @@ -1339,7 +1357,7 @@ static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelForma TRACE("iface %p, format %p.\n", iface, format); - *format = render_target->format; + *format = render_target->desc.pixelFormat; return format; } @@ -1357,8 +1375,8 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_SetDpi(ID2D1RenderTarget *if else if (dpi_x <= 0.0f || dpi_y <= 0.0f) return; - render_target->dpi_x = dpi_x; - render_target->dpi_y = dpi_y; + render_target->desc.dpiX = dpi_x; + render_target->desc.dpiY = dpi_y; } static void STDMETHODCALLTYPE d2d_d3d_render_target_GetDpi(ID2D1RenderTarget *iface, float *dpi_x, float *dpi_y) @@ -1367,8 +1385,8 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_GetDpi(ID2D1RenderTarget *if TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y); - *dpi_x = render_target->dpi_x; - *dpi_y = render_target->dpi_y; + *dpi_x = render_target->desc.dpiX; + *dpi_y = render_target->desc.dpiY; } static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_d3d_render_target_GetSize(ID2D1RenderTarget *iface, D2D1_SIZE_F *size) @@ -1377,8 +1395,8 @@ static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_d3d_render_target_GetSize(ID2D1Render TRACE("iface %p, size %p.\n", iface, size); - size->width = render_target->pixel_size.width / (render_target->dpi_x / 96.0f); - size->height = render_target->pixel_size.height / (render_target->dpi_y / 96.0f); + size->width = render_target->pixel_size.width / (render_target->desc.dpiX / 96.0f); + size->height = render_target->pixel_size.height / (render_target->desc.dpiY / 96.0f); return size; } @@ -1541,7 +1559,7 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_GetPixelsPerDip(IDWriteTextRe TRACE("iface %p, ctx %p, ppd %p.\n", iface, ctx, ppd); - *ppd = render_target->dpi_y / 96.0f; + *ppd = render_target->desc.dpiY / 96.0f; return S_OK; } @@ -1590,7 +1608,7 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawUnderline(IDWriteTextRend iface, ctx, baseline_origin_x, baseline_origin_y, underline, effect); /* minimal thickness in DIPs that will result in at least 1 pixel thick line */ - min_thickness = 96.0f / (render_target->dpi_y * sqrtf(m->_21 * m->_21 + m->_22 * m->_22)); + min_thickness = 96.0f / (render_target->desc.dpiY * sqrtf(m->_21 * m->_21 + m->_22 * m->_22)); rect.left = baseline_origin_x; rect.top = baseline_origin_y + underline->offset; @@ -2167,7 +2185,7 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, goto err; } - render_target->format = desc->pixelFormat; + render_target->desc.pixelFormat = desc->pixelFormat; render_target->pixel_size.width = surface_desc.Width; render_target->pixel_size.height = surface_desc.Height; render_target->drawing_state.transform = identity; @@ -2179,8 +2197,8 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, goto err; } - render_target->dpi_x = dpi_x; - render_target->dpi_y = dpi_y; + render_target->desc.dpiX = dpi_x; + render_target->desc.dpiY = dpi_y; return S_OK; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 433b1a5..d9d240c 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -2993,17 +2993,8 @@ static void test_bitmap_target(void) hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt); -todo_wine ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); - if (FAILED(hr)) - { - ID2D1HwndRenderTarget_Release(hwnd_rt); - DestroyWindow(hwnd_rt_desc.hwnd); - ID2D1Factory_Release(factory); - return; - } - /* See if parent target is referenced. */ ID2D1HwndRenderTarget_AddRef(hwnd_rt); refcount = ID2D1HwndRenderTarget_Release(hwnd_rt); @@ -3059,8 +3050,8 @@ todo_wine ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1); pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(rt); - ok(pixel_size.width == ceilf(size.width * dpi2[0] / 96.0f) - && pixel_size.height == ceilf(size.height * dpi2[1] / 96.0f), "Wrong pixel size %ux%u\n", + ok(pixel_size.width == ceilf(size.width * dpi[0] / 96.0f) + && pixel_size.height == ceilf(size.height * dpi[1] / 96.0f), "Wrong pixel size %ux%u\n", pixel_size.width, pixel_size.height); dpi[0] *= (pixel_size.width / size.width) * (96.0f / dpi[0]); -- 2.9.3 From jacek at codeweavers.com Wed Oct 19 12:05:05 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 19 Oct 2016 19:05:05 +0200 Subject: [PATCH 01/10 v2] server: Introduced iosb struct for server-side IO_STATUS_BLOCK representation and use it in irp_call. Message-ID: v2: Don't store async queues in a list. Signed-off-by: Jacek Caban --- server/async.c | 34 +++++++++++++++++++++++++++++++++ server/device.c | 58 +++++++++++++++++++++++++-------------------------------- server/file.h | 14 ++++++++++++++ 3 files changed, 73 insertions(+), 33 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-server-Introduced-iosb-struct-for-server-side-IO_STAT.diff Type: text/x-patch Size: 7915 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 19 12:05:09 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 19 Oct 2016 19:05:09 +0200 Subject: [PATCH 02/10] server: Store iosb in async object. Message-ID: <3551974d-11d3-18dc-9735-9972b5f115f8@codeweavers.com> Signed-off-by: Jacek Caban --- server/async.c | 15 ++++++++++++++- server/change.c | 2 +- server/device.c | 2 +- server/fd.c | 6 +++--- server/file.h | 5 +++-- server/mailslot.c | 2 +- server/named_pipe.c | 6 +++--- server/serial.c | 2 +- server/sock.c | 4 ++-- 9 files changed, 29 insertions(+), 15 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-server-Store-iosb-in-async-object.diff Type: text/x-patch Size: 9940 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 19 12:05:13 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 19 Oct 2016 19:05:13 +0200 Subject: [PATCH 03/10] server: Use async object to transfer IRP result to client. Message-ID: <97b8512b-e314-aaf4-6a30-f5c3e0f6ab13@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/ntdll/file.c | 2 +- server/async.c | 21 +++++++++++++++++++ server/change.c | 3 ++- server/console.c | 3 ++- server/device.c | 58 ++++++----------------------------------------------- server/fd.c | 43 +++++++++++++++++++++++++++++++++++++++ server/file.c | 3 ++- server/file.h | 5 +++++ server/mailslot.c | 9 ++++++--- server/mapping.c | 3 ++- server/protocol.def | 19 +++++++++--------- server/serial.c | 3 ++- server/sock.c | 6 ++++-- 13 files changed, 105 insertions(+), 73 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0003-server-Use-async-object-to-transfer-IRP-result-to-cli.diff Type: text/x-patch Size: 15241 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 19 12:05:21 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 19 Oct 2016 19:05:21 +0200 Subject: [PATCH 05/10] server: Moved server-independent parts of pipe_server_flush into separated function. Message-ID: <723a8a69-a6f2-7c8f-85ae-99c36c1f9931@codeweavers.com> Signed-off-by: Jacek Caban --- server/named_pipe.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0005-server-Moved-server-independent-parts-of-pipe_server_.diff Type: text/x-patch Size: 2150 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 19 12:05:25 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 19 Oct 2016 19:05:25 +0200 Subject: [PATCH 06/10] server: Signal pipe server fd in create_pipe_servr. Message-ID: Signed-off-by: Jacek Caban --- dlls/kernel32/tests/pipe.c | 8 ++++++++ server/named_pipe.c | 1 + 2 files changed, 9 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0006-server-Signal-pipe-server-fd-in-create_pipe_servr.diff Type: text/x-patch Size: 1412 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 19 12:05:18 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 19 Oct 2016 19:05:18 +0200 Subject: [PATCH 04/10] server: Introduced new pipe_end struct containing common parts of pipe_client and pipe_server. Message-ID: <15843efc-f111-abee-50bf-93af9ab9f76a@codeweavers.com> Signed-off-by: Jacek Caban --- server/named_pipe.c | 99 ++++++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 46 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0004-server-Introduced-new-pipe_end-struct-containing-comm.diff Type: text/x-patch Size: 11647 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 19 12:05:35 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 19 Oct 2016 19:05:35 +0200 Subject: [PATCH 08/10] server: Added support for flushing client pipe. Message-ID: Signed-off-by: Jacek Caban --- server/named_pipe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0008-server-Added-support-for-flushing-client-pipe.diff Type: text/x-patch Size: 669 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 19 12:05:31 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 19 Oct 2016 19:05:31 +0200 Subject: [PATCH 07/10] server: Added support for message mode named pipes. Message-ID: <8e0cc14e-5817-131e-5012-a2c745f23a83@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/kernel32/tests/pipe.c | 74 ++----- dlls/ntdll/file.c | 7 +- dlls/ntdll/tests/file.c | 2 +- server/async.c | 9 + server/file.h | 1 + server/named_pipe.c | 532 ++++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 535 insertions(+), 90 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0007-server-Added-support-for-message-mode-named-pipes.diff Type: text/x-patch Size: 45726 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 19 12:05:40 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 19 Oct 2016 19:05:40 +0200 Subject: [PATCH 09/10] kernel32/tests: Added more named pipe tests. Message-ID: <108ef954-1530-a1a8-e4ec-aa6fdaa71063@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/kernel32/tests/pipe.c | 384 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 384 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0009-kernel32-tests-Added-more-named-pipe-tests.diff Type: text/x-patch Size: 17656 bytes Desc: not available URL: From jacek at codeweavers.com Wed Oct 19 12:05:47 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Wed, 19 Oct 2016 19:05:47 +0200 Subject: [PATCH 10/10] kernel32/tests: Added tests of real buffer size. Message-ID: Signed-off-by: Jacek Caban --- dlls/kernel32/tests/pipe.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0010-kernel32-tests-Added-tests-of-real-buffer-size.diff Type: text/x-patch Size: 2576 bytes Desc: not available URL: From wine.dev at web.de Wed Oct 19 16:27:41 2016 From: wine.dev at web.de (Detlef Riekenberg) Date: Wed, 19 Oct 2016 23:27:41 +0200 Subject: [PATCH] localspl+winspool.drv: Use a better default environment for printers Message-ID: <1476912461-9030-1-git-send-email-wine.dev@web.de> ALPHA and MIPS are unrelevant history, but arm and arm64 are still missing. Who can send me a PI 3 for testing? Or a tablet with Windows RT? -- bye bye ... Detlef Signed-off-by: Detlef Riekenberg --- dlls/localspl/provider.c | 7 +++++++ dlls/winspool.drv/info.c | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index b5fcdb1..3ee8d57 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -708,7 +708,14 @@ static const printenv_t * validate_envW(LPCWSTR env) } else { +#ifdef __x86_64__ + result = &env_x64; +#elif defined (__i386__) result = (GetVersion() & 0x80000000) ? &env_win40 : &env_x86; +#else + ERR("Default env not defined. Fallback to x86\n"); + result = &env_x86; +#endif } TRACE("=> using %p: %s\n", result, debugstr_w(result ? result->envname : NULL)); diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c index 2f0ff3d..442f80a 100644 --- a/dlls/winspool.drv/info.c +++ b/dlls/winspool.drv/info.c @@ -349,8 +349,16 @@ static const printenv_t * validate_envW(LPCWSTR env) } else { +#ifdef __x86_64__ + result = &env_x64; +#elif defined (__i386__) result = (GetVersion() & 0x80000000) ? &env_win40 : &env_x86; +#else + ERR("Default env not defined. Fallback to x86\n"); + result = &env_x86; +#endif } + TRACE("using %p: %s\n", result, debugstr_w(result ? result->envname : NULL)); return result; -- 2.7.4 From leslie_alistair at hotmail.com Thu Oct 20 01:38:56 2016 From: leslie_alistair at hotmail.com (Alistair Leslie-Hughes) Date: Thu, 20 Oct 2016 06:38:56 +0000 Subject: [PATCH v2] comtrl32/treeview: Display state value as hex. Message-ID: Signed-off-by: Alistair Leslie-Hughes --- dlls/comctl32/treeview.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c index 117b309..70d6362 100644 --- a/dlls/comctl32/treeview.c +++ b/dlls/comctl32/treeview.c @@ -4448,7 +4448,7 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect, assert(newSelect == NULL || TREEVIEW_ValidItem(infoPtr, newSelect)); - TRACE("Entering item %p (%s), flag 0x%x, cause 0x%x, state %d\n", + TRACE("Entering item %p (%s), flag 0x%x, cause 0x%x, state 0x%x\n", newSelect, TREEVIEW_ItemName(newSelect), action, cause, newSelect ? newSelect->state : 0); @@ -4523,7 +4523,7 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect, break; } - TRACE("Leaving state %d\n", newSelect ? newSelect->state : 0); + TRACE("Leaving state 0x%x\n", newSelect ? newSelect->state : 0); return TRUE; } -- 1.9.1 From mstefani at redhat.de Thu Oct 20 03:19:08 2016 From: mstefani at redhat.de (Michael Stefaniuc) Date: Thu, 20 Oct 2016 10:19:08 +0200 Subject: mshtml/tests: Use EqualRect() to compare RECTs. Message-ID: <20161020081908.GA23821@redhat.com> Signed-off-by: Michael Stefaniuc --- dlls/mshtml/tests/activex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/mshtml/tests/activex.c b/dlls/mshtml/tests/activex.c index bd1a0cd..78602b7 100644 --- a/dlls/mshtml/tests/activex.c +++ b/dlls/mshtml/tests/activex.c @@ -1149,8 +1149,8 @@ static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, LPMSG lpms ok(ip_frame != NULL, "ip_frame == NULL\n"); ok(ip_uiwindow != NULL, "ip_uiwindow == NULL\n"); ok((IOleInPlaceUIWindow*)ip_frame != ip_uiwindow, "ip_frame == ip_uiwindow\n"); - ok(!memcmp(&pos_rect, lprcPosRect, sizeof(RECT)), "pos_rect != lpecPosRect\n"); - ok(!memcmp(&clip_rect, lprcPosRect, sizeof(RECT)), "clip_rect != lpecPosRect\n"); + ok(EqualRect(&pos_rect, lprcPosRect), "pos_rect != lpecPosRect\n"); + ok(EqualRect(&clip_rect, lprcPosRect), "clip_rect != lpecPosRect\n"); ok(frame_info.cb == sizeof(frame_info), "frame_info.cb = %d\n", frame_info.cb); ok(!frame_info.fMDIApp, "frame_info.fMDIApp = %x\n", frame_info.fMDIApp); ok(frame_info.hwndFrame != NULL, "frame_info.hwnd == NULL\n"); -- 2.7.4 From mstefani at redhat.de Thu Oct 20 03:24:06 2016 From: mstefani at redhat.de (Michael Stefaniuc) Date: Thu, 20 Oct 2016 10:24:06 +0200 Subject: mshtml: Use EqualRect() to compare RECTs. Message-ID: <20161020082406.GB23821@redhat.com> Signed-off-by: Michael Stefaniuc --- dlls/mshtml/pluginhost.c | 2 +- dlls/mshtml/view.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/mshtml/pluginhost.c b/dlls/mshtml/pluginhost.c index 712f7e0..0fbbf6c 100644 --- a/dlls/mshtml/pluginhost.c +++ b/dlls/mshtml/pluginhost.c @@ -311,7 +311,7 @@ void update_plugin_window(PluginHost *host, HWND hwnd, const RECT *rect) TRACE("%p %s\n", hwnd, wine_dbgstr_rect(rect)); - if(memcmp(rect, &host->rect, sizeof(RECT))) { + if(!EqualRect(rect, &host->rect)) { host->rect = *rect; rect_changed = TRUE; } diff --git a/dlls/mshtml/view.c b/dlls/mshtml/view.c index 2a55938..15f39f4 100644 --- a/dlls/mshtml/view.c +++ b/dlls/mshtml/view.c @@ -507,7 +507,7 @@ static HRESULT WINAPI OleDocumentView_SetRect(IOleDocumentView *iface, LPRECT pr if(This->doc_obj->hwnd) { GetClientRect(This->doc_obj->hwnd, &rect); - if(memcmp(prcView, &rect, sizeof(RECT))) { + if(!EqualRect(prcView, &rect)) { InvalidateRect(This->doc_obj->hwnd, NULL, TRUE); SetWindowPos(This->doc_obj->hwnd, NULL, prcView->left, prcView->top, prcView->right, prcView->bottom, SWP_NOZORDER | SWP_NOACTIVATE); -- 2.7.4 From jkucia at codeweavers.com Thu Oct 20 05:50:50 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Thu, 20 Oct 2016 12:50:50 +0200 Subject: [PATCH 1/9] wined3d: Introduce wined3d_buffer_prepapre_location(). Message-ID: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index c7f0d81..558be1b 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -538,6 +538,32 @@ ULONG CDECL wined3d_buffer_incref(struct wined3d_buffer *buffer) return refcount; } +static BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer, + struct wined3d_context *context, DWORD location) +{ + switch (location) + { + case WINED3D_LOCATION_SYSMEM: + if (buffer->resource.heap_memory) + return TRUE; + + if (!wined3d_resource_allocate_sysmem(&buffer->resource)) + { + ERR("Failed to allocate system memory.\n"); + return FALSE; + } + return TRUE; + + case WINED3D_LOCATION_BUFFER: + FIXME("Not implemented yet.\n"); + return FALSE; + + default: + ERR("Invalid location %s.\n", wined3d_debug_location(location)); + return FALSE; + } +} + /* Context activation is done by the caller. */ BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) { @@ -547,8 +573,8 @@ BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_c if (buffer->resource.heap_memory) return buffer->resource.heap_memory; - if (!wined3d_resource_allocate_sysmem(&buffer->resource)) - ERR("Failed to allocate system memory.\n"); + if (!wined3d_buffer_prepare_location(buffer, context, WINED3D_LOCATION_SYSMEM)) + return NULL; buffer_bind(buffer, context); GL_EXTCALL(glGetBufferSubData(buffer->buffer_type_hint, 0, buffer->resource.size, buffer->resource.heap_memory)); -- 2.7.3 From jkucia at codeweavers.com Thu Oct 20 05:50:51 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Thu, 20 Oct 2016 12:50:51 +0200 Subject: [PATCH 2/9] wined3d: Introduce wined3d_buffer_load_location(). In-Reply-To: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476960658-29001-2-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 66 ++++++++++++++++++++++++++++++++++-------- dlls/wined3d/wined3d_private.h | 2 ++ 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 558be1b..94b290f 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -564,25 +564,67 @@ static BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer, } } -/* Context activation is done by the caller. */ -BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) +BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer, + struct wined3d_context *context, DWORD location) { const struct wined3d_gl_info *gl_info = context->gl_info; - /* Heap_memory exists if the buffer is double buffered or has no buffer object at all. */ - if (buffer->resource.heap_memory) - return buffer->resource.heap_memory; + TRACE("buffer %p, context %p, location %s.\n", + buffer, context, wined3d_debug_location(location)); + + if (buffer->locations & location) + { + TRACE("Location (%#x) is already up to date.\n", location); + return WINED3D_OK; + } + + if (!buffer->locations) + { + ERR("Buffer %p does not have any up to date location.\n", buffer); + wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_DISCARDED); + return wined3d_buffer_load_location(buffer, context, location); + } + + TRACE("Current buffer location %s.\n", wined3d_debug_location(buffer->locations)); + + if (!wined3d_buffer_prepare_location(buffer, context, location)) + return FALSE; + + if (buffer->locations & WINED3D_LOCATION_DISCARDED) + { + TRACE("Buffer previously discarded, nothing to do.\n"); + wined3d_buffer_validate_location(buffer, location); + wined3d_buffer_invalidate_location(buffer, WINED3D_LOCATION_DISCARDED); + return TRUE; + } + + switch (location) + { + case WINED3D_LOCATION_SYSMEM: + buffer_bind(buffer, context); + GL_EXTCALL(glGetBufferSubData(buffer->buffer_type_hint, 0, buffer->resource.size, + buffer->resource.heap_memory)); + checkGLcall("buffer download"); + buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER; + break; - if (!wined3d_buffer_prepare_location(buffer, context, WINED3D_LOCATION_SYSMEM)) - return NULL; + case WINED3D_LOCATION_BUFFER: + FIXME("Not implemented yet.\n"); + return FALSE; - buffer_bind(buffer, context); - GL_EXTCALL(glGetBufferSubData(buffer->buffer_type_hint, 0, buffer->resource.size, buffer->resource.heap_memory)); - checkGLcall("buffer download"); - buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER; + default: + ERR("Invalid location %s.\n", wined3d_debug_location(location)); + return FALSE; + } - wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_SYSMEM); + wined3d_buffer_validate_location(buffer, location); + return TRUE; +} +/* Context activation is done by the caller. */ +BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) +{ + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); return buffer->resource.heap_memory; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 45a24f1..8001e5e 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3185,6 +3185,8 @@ void buffer_mark_used(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; void wined3d_buffer_invalidate_location(struct wined3d_buffer *buffer, DWORD location) DECLSPEC_HIDDEN; void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_state *state) DECLSPEC_HIDDEN; +BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer, struct wined3d_context *context, + DWORD location) DECLSPEC_HIDDEN; BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) DECLSPEC_HIDDEN; HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_offset, struct wined3d_buffer *src_buffer, unsigned int src_offset, unsigned int size) DECLSPEC_HIDDEN; -- 2.7.3 From jkucia at codeweavers.com Thu Oct 20 05:50:52 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Thu, 20 Oct 2016 12:50:52 +0200 Subject: [PATCH 3/9] wined3d: Do not assume that WINED3D_LOCATION_SYSMEM is always valid for double buffered buffers. In-Reply-To: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476960658-29001-3-git-send-email-jkucia@codeweavers.com> We now have API that allows invalidating locations for buffers. Signed-off-by: Józef Kucia --- wined3d_buffer_load() still requires additional changes --- dlls/wined3d/buffer.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 94b290f..4a4d367 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -975,13 +975,13 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context * if (!buffer->conversion_map) { /* That means that there is nothing to fixup. Just upload from - * buffer->resource.heap_memory directly into the vbo. Do not + * buffer->resource.heap_memory directly into the BO. Do not * free the system memory copy because drawPrimitive may need it if * the stride is 0, for instancing emulation, vertex blending * emulation or shader emulation. */ TRACE("No conversion needed.\n"); - /* Nothing to do because we locked directly into the vbo */ + /* Nothing to do because heap memory exists if the buffer is double buffer or has no BO at all. */ if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) return; @@ -1056,6 +1056,8 @@ struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffe static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UINT size, BYTE **data, DWORD flags) { + struct wined3d_device *device = buffer->resource.device; + struct wined3d_context *context; LONG count; BYTE *base; @@ -1087,6 +1089,13 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI if (buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER) { + if (!(buffer->locations & WINED3D_LOCATION_SYSMEM)) + { + context = context_acquire(device, NULL); + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); + context_release(context); + } + if (!(flags & WINED3D_MAP_READONLY)) wined3d_buffer_invalidate_range(buffer, WINED3D_LOCATION_BUFFER, dirty_offset, dirty_size); } @@ -1097,8 +1106,6 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI if (count == 1) { - struct wined3d_device *device = buffer->resource.device; - struct wined3d_context *context; const struct wined3d_gl_info *gl_info; context = context_acquire(device, NULL); @@ -1254,6 +1261,11 @@ HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_ dst_buffer_mem = dst_buffer->resource.heap_memory; src_buffer_mem = src_buffer->resource.heap_memory; + if (dst_buffer_mem && (dst_offset || size != dst_buffer->resource.size)) + wined3d_buffer_load_location(dst_buffer, context, WINED3D_LOCATION_SYSMEM); + if (src_buffer_mem) + wined3d_buffer_load_location(src_buffer, context, WINED3D_LOCATION_SYSMEM); + if (!dst_buffer_mem && !src_buffer_mem) { if (gl_info->supported[ARB_COPY_BUFFER]) -- 2.7.3 From jkucia at codeweavers.com Thu Oct 20 05:50:53 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Thu, 20 Oct 2016 12:50:53 +0200 Subject: [PATCH 4/9] wined3d: Move buffer_get_memory() under wined3d_buffer_load_sysmem(). In-Reply-To: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476960658-29001-4-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 4a4d367..8f356d8 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -504,31 +504,6 @@ static inline unsigned int fixup_transformed_pos(float *p) return 4 * sizeof(*p); } -/* Context activation is done by the caller. */ -void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *context, - struct wined3d_bo_address *data) -{ - data->buffer_object = buffer->buffer_object; - if (!buffer->buffer_object) - { - if ((buffer->flags & WINED3D_BUFFER_USE_BO) && !buffer->resource.map_count) - { - buffer_create_buffer_object(buffer, context); - if (buffer->buffer_object) - { - data->buffer_object = buffer->buffer_object; - data->addr = NULL; - return; - } - } - data->addr = buffer->resource.heap_memory; - } - else - { - data->addr = NULL; - } -} - ULONG CDECL wined3d_buffer_incref(struct wined3d_buffer *buffer) { ULONG refcount = InterlockedIncrement(&buffer->resource.ref); @@ -628,6 +603,31 @@ BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_c return buffer->resource.heap_memory; } +/* Context activation is done by the caller. */ +void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *context, + struct wined3d_bo_address *data) +{ + data->buffer_object = buffer->buffer_object; + if (!buffer->buffer_object) + { + if ((buffer->flags & WINED3D_BUFFER_USE_BO) && !buffer->resource.map_count) + { + buffer_create_buffer_object(buffer, context); + if (buffer->buffer_object) + { + data->buffer_object = buffer->buffer_object; + data->addr = NULL; + return; + } + } + data->addr = buffer->resource.heap_memory; + } + else + { + data->addr = NULL; + } +} + static void buffer_unload(struct wined3d_resource *resource) { struct wined3d_buffer *buffer = buffer_from_resource(resource); -- 2.7.3 From jkucia at codeweavers.com Thu Oct 20 05:50:54 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Thu, 20 Oct 2016 12:50:54 +0200 Subject: [PATCH 5/9] wined3d: Implement wined3d_buffer_prepare_location() for WINED3D_LOCATION_BUFFER. In-Reply-To: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476960658-29001-5-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 104 +++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 8f356d8..e559586 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -162,20 +162,20 @@ static void delete_gl_buffer(struct wined3d_buffer *This, const struct wined3d_g } /* Context activation is done by the caller. */ -static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wined3d_context *context) +static BOOL buffer_create_buffer_object(struct wined3d_buffer *buffer, struct wined3d_context *context) { - GLenum gl_usage = GL_STATIC_DRAW_ARB; - GLenum error; const struct wined3d_gl_info *gl_info = context->gl_info; + GLenum gl_usage = GL_STATIC_DRAW; + GLenum error; - TRACE("Creating an OpenGL vertex buffer object for wined3d_buffer %p with usage %s.\n", - This, debug_d3dusage(This->resource.usage)); + TRACE("Creating an OpenGL buffer object for wined3d_buffer %p with usage %s.\n", + buffer, debug_d3dusage(buffer->resource.usage)); /* Make sure that the gl error is cleared. Do not use checkGLcall - * here because checkGLcall just prints a fixme and continues. However, - * if an error during VBO creation occurs we can fall back to non-vbo operation - * with full functionality(but performance loss) - */ + * here because checkGLcall just prints a fixme and continues. However, + * if an error during VBO creation occurs we can fall back to non-VBO operation + * with full functionality(but performance loss). + */ while (gl_info->gl_ops.gl.p_glGetError() != GL_NO_ERROR); /* Basically the FVF parameter passed to CreateVertexBuffer is no good. @@ -184,72 +184,72 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine * to be verified to check if the rhw and color values are in the correct * format. */ - GL_EXTCALL(glGenBuffers(1, &This->buffer_object)); + GL_EXTCALL(glGenBuffers(1, &buffer->buffer_object)); error = gl_info->gl_ops.gl.p_glGetError(); - if (!This->buffer_object || error != GL_NO_ERROR) + if (!buffer->buffer_object || error != GL_NO_ERROR) { - ERR("Failed to create a VBO with error %s (%#x)\n", debug_glerror(error), error); + ERR("Failed to create a BO with error %s (%#x).\n", debug_glerror(error), error); goto fail; } - buffer_bind(This, context); + buffer_bind(buffer, context); error = gl_info->gl_ops.gl.p_glGetError(); if (error != GL_NO_ERROR) { - ERR("Failed to bind the VBO with error %s (%#x)\n", debug_glerror(error), error); + ERR("Failed to bind the BO with error %s (%#x).\n", debug_glerror(error), error); goto fail; } - if (This->resource.usage & WINED3DUSAGE_DYNAMIC) + if (buffer->resource.usage & WINED3DUSAGE_DYNAMIC) { TRACE("Buffer has WINED3DUSAGE_DYNAMIC set.\n"); gl_usage = GL_STREAM_DRAW_ARB; - if(gl_info->supported[APPLE_FLUSH_BUFFER_RANGE]) + if (gl_info->supported[APPLE_FLUSH_BUFFER_RANGE]) { - GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)); - checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)"); - GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)); - checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)"); - This->flags |= WINED3D_BUFFER_APPLESYNC; + GL_EXTCALL(glBufferParameteriAPPLE(buffer->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)); + GL_EXTCALL(glBufferParameteriAPPLE(buffer->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)); + checkGLcall("glBufferParameteriAPPLE"); + buffer->flags |= WINED3D_BUFFER_APPLESYNC; } - /* No setup is needed here for GL_ARB_map_buffer_range */ + /* No setup is needed here for GL_ARB_map_buffer_range. */ } /* Reserve memory for the buffer. The amount of data won't change * so we are safe with calling glBufferData once and * calling glBufferSubData on updates. Upload the actual data in case - * we're not double buffering, so we can release the heap mem afterwards + * we're not double buffering, so we can release the heap mem afterwards. */ - GL_EXTCALL(glBufferData(This->buffer_type_hint, This->resource.size, This->resource.heap_memory, gl_usage)); + GL_EXTCALL(glBufferData(buffer->buffer_type_hint, buffer->resource.size, buffer->resource.heap_memory, gl_usage)); error = gl_info->gl_ops.gl.p_glGetError(); if (error != GL_NO_ERROR) { - ERR("glBufferData failed with error %s (%#x)\n", debug_glerror(error), error); + ERR("glBufferData failed with error %s (%#x).\n", debug_glerror(error), error); goto fail; } - This->buffer_object_usage = gl_usage; + buffer->buffer_object_usage = gl_usage; - if (This->flags & WINED3D_BUFFER_DOUBLEBUFFER) + if (buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER) { - buffer_invalidate_bo_range(This, 0, 0); + buffer_invalidate_bo_range(buffer, 0, 0); } else { - wined3d_resource_free_sysmem(&This->resource); - wined3d_buffer_validate_location(This, WINED3D_LOCATION_BUFFER); - wined3d_buffer_invalidate_location(This, WINED3D_LOCATION_SYSMEM); + wined3d_resource_free_sysmem(&buffer->resource); + wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_BUFFER); + wined3d_buffer_invalidate_location(buffer, WINED3D_LOCATION_SYSMEM); } - return; + return TRUE; fail: - /* Clean up all VBO init, but continue because we can work without a VBO :-) */ - ERR("Failed to create a vertex buffer object. Continuing, but performance issues may occur.\n"); - This->flags &= ~WINED3D_BUFFER_USE_BO; - delete_gl_buffer(This, gl_info); - buffer_clear_dirty_areas(This); + /* Clean up all BO init, but continue because we can work without a BO :-) */ + ERR("Failed to create a buffer object. Continuing, but performance issues may occur.\n"); + buffer->flags &= ~WINED3D_BUFFER_USE_BO; + delete_gl_buffer(buffer, gl_info); + buffer_clear_dirty_areas(buffer); + return FALSE; } static BOOL buffer_process_converted_attribute(struct wined3d_buffer *buffer, @@ -530,8 +530,15 @@ static BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer, return TRUE; case WINED3D_LOCATION_BUFFER: - FIXME("Not implemented yet.\n"); - return FALSE; + if (buffer->buffer_object) + return TRUE; + + if (!(buffer->flags & WINED3D_BUFFER_USE_BO)) + { + WARN("Trying to create BO for buffer %p with no WINED3D_BUFFER_USE_BO.\n", buffer); + return FALSE; + } + return buffer_create_buffer_object(buffer, context); default: ERR("Invalid location %s.\n", wined3d_debug_location(location)); @@ -612,7 +619,7 @@ void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *co { if ((buffer->flags & WINED3D_BUFFER_USE_BO) && !buffer->resource.map_count) { - buffer_create_buffer_object(buffer, context); + wined3d_buffer_prepare_location(buffer, context, WINED3D_LOCATION_BUFFER); if (buffer->buffer_object) { data->buffer_object = buffer->buffer_object; @@ -878,20 +885,15 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context * buffer_mark_used(buffer); - if (!buffer->buffer_object) + /* TODO: Make converting independent from VBOs */ + if (!(buffer->flags & WINED3D_BUFFER_USE_BO)) { - /* TODO: Make converting independent from VBOs */ - if (buffer->flags & WINED3D_BUFFER_USE_BO) - { - buffer_create_buffer_object(buffer, context); - } - else - { - /* Not doing any conversion */ - return; - } + /* Not doing any conversion */ + return; } + wined3d_buffer_prepare_location(buffer, context, WINED3D_LOCATION_BUFFER); + /* Reading the declaration makes only sense if we have valid state information * (i.e., if this function is called during draws). */ if (state) -- 2.7.3 From jkucia at codeweavers.com Thu Oct 20 05:50:55 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Thu, 20 Oct 2016 12:50:55 +0200 Subject: [PATCH 6/9] wined3d: Replace wined3d_buffer_load_sysmem() calls with wined3d_buffer_load_location(). In-Reply-To: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476960658-29001-6-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 14 +++++--------- dlls/wined3d/context.c | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index e559586..ebf95c4 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -648,12 +648,9 @@ static void buffer_unload(struct wined3d_resource *resource) context = context_acquire(device, NULL); - /* Download the buffer, but don't permanently enable double buffering */ - if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) - { - wined3d_buffer_load_sysmem(buffer, context); - buffer->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER; - } + /* Download the buffer, but don't permanently enable double buffering. */ + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); + buffer->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER; wined3d_buffer_invalidate_location(buffer, WINED3D_LOCATION_BUFFER); delete_gl_buffer(buffer, context->gl_info); @@ -995,8 +992,7 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context * if (buffer->buffer_type_hint != GL_ARRAY_BUFFER) ERR("Converting data in non-vertex buffer.\n"); - if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) - wined3d_buffer_load_sysmem(buffer, context); + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); /* Now for each vertex in the buffer that needs conversion */ vertex_count = buffer->resource.size / buffer->stride; @@ -1151,7 +1147,7 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI else { TRACE("Falling back to doublebuffered operation.\n"); - wined3d_buffer_load_sysmem(buffer, context); + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); } TRACE("New pointer is %p.\n", buffer->resource.heap_memory); buffer->map_ptr = NULL; diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 1ca12bc..a7835f6 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -3432,7 +3432,7 @@ BOOL context_apply_draw_state(struct wined3d_context *context, if (context->stream_info.all_vbo) wined3d_buffer_load(state->index_buffer, context, state); else - wined3d_buffer_load_sysmem(state->index_buffer, context); + wined3d_buffer_load_location(state->index_buffer, context, WINED3D_LOCATION_SYSMEM); } for (i = 0; i < context->numDirtyEntries; ++i) -- 2.7.3 From jkucia at codeweavers.com Thu Oct 20 05:50:56 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Thu, 20 Oct 2016 12:50:56 +0200 Subject: [PATCH 7/9] wined3d: Introduce buffer_conversion_upload() helper function. In-Reply-To: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476960658-29001-7-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 122 +++++++++++++++++++++++++++----------------------- 1 file changed, 65 insertions(+), 57 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index ebf95c4..7a66283 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -857,6 +857,69 @@ static void buffer_direct_upload(struct wined3d_buffer *This, struct wined3d_con wined3d_buffer_validate_location(This, WINED3D_LOCATION_BUFFER); } +static void buffer_conversion_upload(struct wined3d_buffer *buffer, struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int i, j, start, end, len, vertex_count; + BYTE *data; + + /* This would potentially invalidate the element array buffer binding. */ + if (buffer->buffer_type_hint != GL_ARRAY_BUFFER) + ERR("Converting data in non-vertex buffer.\n"); + + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); + + /* Now for each vertex in the buffer that needs conversion */ + vertex_count = buffer->resource.size / buffer->stride; + + if (!(data = HeapAlloc(GetProcessHeap(), 0, buffer->resource.size))) + { + ERR("Out of memory.\n"); + return; + } + + while (buffer->modified_areas) + { + buffer->modified_areas--; + start = buffer->maps[buffer->modified_areas].offset; + len = buffer->maps[buffer->modified_areas].size; + end = start + len; + + memcpy(data + start, (BYTE *)buffer->resource.heap_memory + start, end - start); + for (i = start / buffer->stride; i < min((end / buffer->stride) + 1, vertex_count); ++i) + { + for (j = 0; j < buffer->stride;) + { + switch (buffer->conversion_map[j]) + { + case CONV_NONE: + /* Done already */ + j += sizeof(DWORD); + break; + case CONV_D3DCOLOR: + j += fixup_d3dcolor((DWORD *) (data + i * buffer->stride + j)); + break; + case CONV_POSITIONT: + j += fixup_transformed_pos((float *) (data + i * buffer->stride + j)); + break; + default: + FIXME("Unimplemented conversion %d in shifted conversion.\n", buffer->conversion_map[j]); + ++j; + } + } + } + + GL_EXTCALL(glBindBuffer(buffer->buffer_type_hint, buffer->buffer_object)); + checkGLcall("glBindBuffer"); + GL_EXTCALL(glBufferSubData(buffer->buffer_type_hint, start, len, data + start)); + checkGLcall("glBufferSubData"); + } + + HeapFree(GetProcessHeap(), 0, data); + + wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_BUFFER); +} + void buffer_mark_used(struct wined3d_buffer *buffer) { buffer->flags &= ~(WINED3D_BUFFER_SYNC | WINED3D_BUFFER_DISCARD); @@ -868,9 +931,7 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context * { DWORD flags = buffer->flags & (WINED3D_BUFFER_SYNC | WINED3D_BUFFER_DISCARD); const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int i, j, start, end, len, vertex_count; BOOL decl_changed = FALSE; - BYTE *data; TRACE("buffer %p.\n", buffer); @@ -985,64 +1046,11 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context * return; buffer_direct_upload(buffer, context, flags); - return; - } - - /* This would potentially invalidate the element array buffer binding. */ - if (buffer->buffer_type_hint != GL_ARRAY_BUFFER) - ERR("Converting data in non-vertex buffer.\n"); - - wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); - - /* Now for each vertex in the buffer that needs conversion */ - vertex_count = buffer->resource.size / buffer->stride; - - if (!(data = HeapAlloc(GetProcessHeap(), 0, buffer->resource.size))) - { - ERR("Out of memory.\n"); - return; } - - while (buffer->modified_areas) + else { - buffer->modified_areas--; - start = buffer->maps[buffer->modified_areas].offset; - len = buffer->maps[buffer->modified_areas].size; - end = start + len; - - memcpy(data + start, (BYTE *)buffer->resource.heap_memory + start, end - start); - for (i = start / buffer->stride; i < min((end / buffer->stride) + 1, vertex_count); ++i) - { - for (j = 0; j < buffer->stride;) - { - switch (buffer->conversion_map[j]) - { - case CONV_NONE: - /* Done already */ - j += sizeof(DWORD); - break; - case CONV_D3DCOLOR: - j += fixup_d3dcolor((DWORD *) (data + i * buffer->stride + j)); - break; - case CONV_POSITIONT: - j += fixup_transformed_pos((float *) (data + i * buffer->stride + j)); - break; - default: - FIXME("Unimplemented conversion %d in shifted conversion.\n", buffer->conversion_map[j]); - ++j; - } - } - } - - GL_EXTCALL(glBindBuffer(buffer->buffer_type_hint, buffer->buffer_object)); - checkGLcall("glBindBuffer"); - GL_EXTCALL(glBufferSubData(buffer->buffer_type_hint, start, len, data + start)); - checkGLcall("glBufferSubData"); + buffer_conversion_upload(buffer, context); } - - HeapFree(GetProcessHeap(), 0, data); - - wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_BUFFER); } struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffer *buffer) -- 2.7.3 From jkucia at codeweavers.com Thu Oct 20 05:50:57 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Thu, 20 Oct 2016 12:50:57 +0200 Subject: [PATCH 8/9] wined3d: Introduce wined3d_buffer_get_memory(). In-Reply-To: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476960658-29001-8-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 26 +++++++++++++++++++++++++- dlls/wined3d/context.c | 2 +- dlls/wined3d/wined3d_private.h | 4 ++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 7a66283..08cbfc2 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -611,7 +611,7 @@ BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_c } /* Context activation is done by the caller. */ -void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *context, +static void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *context, struct wined3d_bo_address *data) { data->buffer_object = buffer->buffer_object; @@ -635,6 +635,30 @@ void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *co } } +void wined3d_buffer_get_memory(struct wined3d_buffer *buffer, + struct wined3d_bo_address *data, DWORD locations) +{ + TRACE("buffer %p, data %p, locations %s.\n", + buffer, data, wined3d_debug_location(locations)); + + if (locations & WINED3D_LOCATION_BUFFER) + { + data->buffer_object = buffer->buffer_object; + data->addr = NULL; + return; + } + if (locations & WINED3D_LOCATION_SYSMEM) + { + data->buffer_object = 0; + data->addr = buffer->resource.heap_memory; + return; + } + + ERR("Unexpected locations %s.\n", wined3d_debug_location(locations)); + data->buffer_object = 0; + data->addr = NULL; +} + static void buffer_unload(struct wined3d_resource *resource) { struct wined3d_buffer *buffer = buffer_from_resource(resource); diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index a7835f6..594f55f 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -3201,7 +3201,7 @@ static void context_update_stream_info(struct wined3d_context *context, const st else { wined3d_buffer_load(buffer, context, state); - buffer_get_memory(buffer, context, &data); + wined3d_buffer_get_memory(buffer, &data, buffer->locations); element->data.buffer_object = data.buffer_object; element->data.addr += (ULONG_PTR)data.addr; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 8001e5e..4e7bb88 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3179,9 +3179,9 @@ static inline struct wined3d_buffer *buffer_from_resource(struct wined3d_resourc return CONTAINING_RECORD(resource, struct wined3d_buffer, resource); } -void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *context, - struct wined3d_bo_address *data) DECLSPEC_HIDDEN; void buffer_mark_used(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; +void wined3d_buffer_get_memory(struct wined3d_buffer *buffer, + struct wined3d_bo_address *data, DWORD locations) DECLSPEC_HIDDEN; void wined3d_buffer_invalidate_location(struct wined3d_buffer *buffer, DWORD location) DECLSPEC_HIDDEN; void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_state *state) DECLSPEC_HIDDEN; -- 2.7.3 From jkucia at codeweavers.com Thu Oct 20 05:50:58 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Thu, 20 Oct 2016 12:50:58 +0200 Subject: [PATCH 9/9] wined3d: Prefer current locations to WINED3D_LOCATION_SYSMEM in wined3d_buffer_copy(). In-Reply-To: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1476960658-29001-9-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 71 ++++++++++++--------------------------------------- 1 file changed, 17 insertions(+), 54 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 08cbfc2..94406f7 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -111,12 +111,6 @@ static void wined3d_buffer_invalidate_range(struct wined3d_buffer *buffer, DWORD TRACE("buffer %p, location %s, offset %u, size %u.\n", buffer, wined3d_debug_location(location), offset, size); - if ((offset || size) && (location & ~WINED3D_LOCATION_BUFFER)) - { - ERR("Range can be invalidated only for WINED3D_LOCATION_BUFFER.\n"); - return; - } - if (location & WINED3D_LOCATION_BUFFER) buffer_invalidate_bo_range(buffer, offset, size); @@ -610,31 +604,6 @@ BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_c return buffer->resource.heap_memory; } -/* Context activation is done by the caller. */ -static void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *context, - struct wined3d_bo_address *data) -{ - data->buffer_object = buffer->buffer_object; - if (!buffer->buffer_object) - { - if ((buffer->flags & WINED3D_BUFFER_USE_BO) && !buffer->resource.map_count) - { - wined3d_buffer_prepare_location(buffer, context, WINED3D_LOCATION_BUFFER); - if (buffer->buffer_object) - { - data->buffer_object = buffer->buffer_object; - data->addr = NULL; - return; - } - } - data->addr = buffer->resource.heap_memory; - } - else - { - data->addr = NULL; - } -} - void wined3d_buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_bo_address *data, DWORD locations) { @@ -1273,11 +1242,12 @@ static void wined3d_buffer_unmap(struct wined3d_buffer *buffer) HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_offset, struct wined3d_buffer *src_buffer, unsigned int src_offset, unsigned int size) { - BYTE *dst_buffer_mem, *src_buffer_mem, *dst_ptr, *src_ptr; - struct wined3d_bo_address dst_bo_address, src_bo_address; const struct wined3d_gl_info *gl_info; + struct wined3d_bo_address dst, src; struct wined3d_context *context; struct wined3d_device *device; + BYTE *dst_ptr, *src_ptr; + DWORD dst_location; HRESULT hr; device = dst_buffer->resource.device; @@ -1285,24 +1255,17 @@ HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_ context = context_acquire(device, NULL); gl_info = context->gl_info; - buffer_get_memory(dst_buffer, context, &dst_bo_address); - buffer_get_memory(src_buffer, context, &src_bo_address); - - dst_buffer_mem = dst_buffer->resource.heap_memory; - src_buffer_mem = src_buffer->resource.heap_memory; - - if (dst_buffer_mem && (dst_offset || size != dst_buffer->resource.size)) - wined3d_buffer_load_location(dst_buffer, context, WINED3D_LOCATION_SYSMEM); - if (src_buffer_mem) - wined3d_buffer_load_location(src_buffer, context, WINED3D_LOCATION_SYSMEM); + wined3d_buffer_get_memory(dst_buffer, &dst, dst_buffer->locations); + wined3d_buffer_get_memory(src_buffer, &src, src_buffer->locations); - if (!dst_buffer_mem && !src_buffer_mem) + if (dst.buffer_object && src.buffer_object) { if (gl_info->supported[ARB_COPY_BUFFER]) { - GL_EXTCALL(glBindBuffer(GL_COPY_READ_BUFFER, src_bo_address.buffer_object)); - GL_EXTCALL(glBindBuffer(GL_COPY_WRITE_BUFFER, dst_bo_address.buffer_object)); - GL_EXTCALL(glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, src_offset, dst_offset, size)); + GL_EXTCALL(glBindBuffer(GL_COPY_READ_BUFFER, src.buffer_object)); + GL_EXTCALL(glBindBuffer(GL_COPY_WRITE_BUFFER, dst.buffer_object)); + GL_EXTCALL(glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, + src_offset, dst_offset, size)); checkGLcall("direct buffer copy"); } else @@ -1327,25 +1290,25 @@ HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_ wined3d_buffer_unmap(dst_buffer); } } - else if (dst_buffer_mem && !src_buffer_mem) + else if (!dst.buffer_object && src.buffer_object) { buffer_bind(src_buffer, context); - GL_EXTCALL(glGetBufferSubData(src_buffer->buffer_type_hint, src_offset, size, dst_buffer_mem + dst_offset)); + GL_EXTCALL(glGetBufferSubData(src_buffer->buffer_type_hint, src_offset, size, dst.addr + dst_offset)); checkGLcall("buffer download"); } - else if (!dst_buffer_mem && src_buffer_mem) + else if (dst.buffer_object && !src.buffer_object) { buffer_bind(dst_buffer, context); - GL_EXTCALL(glBufferSubData(dst_buffer->buffer_type_hint, dst_offset, size, src_buffer_mem + src_offset)); + GL_EXTCALL(glBufferSubData(dst_buffer->buffer_type_hint, dst_offset, size, src.addr + src_offset)); checkGLcall("buffer upload"); } else { - memcpy(dst_buffer_mem + dst_offset, src_buffer_mem + src_offset, size); + memcpy(dst.addr + dst_offset, src.addr + src_offset, size); } - if (dst_buffer_mem) - wined3d_buffer_invalidate_range(dst_buffer, WINED3D_LOCATION_BUFFER, dst_offset, size); + dst_location = dst.buffer_object ? WINED3D_LOCATION_BUFFER : WINED3D_LOCATION_SYSMEM; + wined3d_buffer_invalidate_range(dst_buffer, ~dst_location, dst_offset, size); context_release(context); return WINED3D_OK; -- 2.7.3 From frederic.delanoy at gmail.com Thu Oct 20 06:43:01 2016 From: frederic.delanoy at gmail.com (=?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delanoy?=) Date: Thu, 20 Oct 2016 13:43:01 +0200 Subject: [website] French translation for release 1.9.21 Message-ID: <20161020114301.10729-1-frederic.delanoy@gmail.com> Signed-off-by: Frédéric Delanoy --- news/fr/2016101401.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 news/fr/2016101401.xml diff --git a/news/fr/2016101401.xml b/news/fr/2016101401.xml new file mode 100644 index 0000000..4e77439 --- /dev/null +++ b/news/fr/2016101401.xml @@ -0,0 +1,14 @@ + +14 octobre 2016 +Sortie de Wine 1.9.21 + +

La version de développement 1.9.21 de Wine est disponible.

+

Nouveautés de cette version : +

    +
  • Version initiale du minipilote HID.
  • +
  • Prise en charge des listes dans le contrôle RichEdit.
  • +
  • Améliorations dans la zone de notifications système.
  • +
  • Diverses corrections de bugs.
  • +

+

Le code source est disponible dès à présent. Les paquets binaires sont en cours de construction, et apparaîtront sous peu sur leurs sites de téléchargement respectifs. +

-- 2.10.1 From hverbeet at codeweavers.com Thu Oct 20 07:45:42 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Thu, 20 Oct 2016 14:45:42 +0200 Subject: [v2 PATCH] d2d1: Initial implementation of bitmap render target In-Reply-To: <20161019170021.19572-1-nsivov@codeweavers.com> References: <20161019170021.19572-1-nsivov@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From piotr at codeweavers.com Thu Oct 20 08:58:49 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Thu, 20 Oct 2016 15:58:49 +0200 Subject: [1/6] msvcirt: Don't return negative values in in_avail and out_waiting. In-Reply-To: <1476878456-8303-1-git-send-email-matellanesivan@gmail.com> References: <1476878456-8303-1-git-send-email-matellanesivan@gmail.com> Message-ID: <593066d9-6f5e-f263-31eb-c14fb8e57fea@codeweavers.com> Signed-off-by: Piotr Caban From piotr at codeweavers.com Thu Oct 20 08:58:54 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Thu, 20 Oct 2016 15:58:54 +0200 Subject: [2/6] msvcirt: Add a partial implementation of class ostrstream. In-Reply-To: <1476878456-8303-2-git-send-email-matellanesivan@gmail.com> References: <1476878456-8303-2-git-send-email-matellanesivan@gmail.com> Message-ID: Signed-off-by: Piotr Caban From piotr at codeweavers.com Thu Oct 20 08:58:58 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Thu, 20 Oct 2016 15:58:58 +0200 Subject: [3/6] msvcirt: Implement ostrstream constructors. In-Reply-To: <1476878456-8303-3-git-send-email-matellanesivan@gmail.com> References: <1476878456-8303-3-git-send-email-matellanesivan@gmail.com> Message-ID: <9583e6e9-8772-0eaa-33fc-d6b5bec1126b@codeweavers.com> Signed-off-by: Piotr Caban From piotr at codeweavers.com Thu Oct 20 08:59:01 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Thu, 20 Oct 2016 15:59:01 +0200 Subject: [4/6] msvcirt/tests: Add tests of ostrstream::pcount. In-Reply-To: <1476878456-8303-4-git-send-email-matellanesivan@gmail.com> References: <1476878456-8303-4-git-send-email-matellanesivan@gmail.com> Message-ID: <03c3678c-3cf5-5248-125d-341189a95d29@codeweavers.com> Signed-off-by: Piotr Caban From piotr at codeweavers.com Thu Oct 20 08:59:05 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Thu, 20 Oct 2016 15:59:05 +0200 Subject: [5/6] msvcirt: Add a partial implementation of class istrstream. In-Reply-To: <1476878456-8303-5-git-send-email-matellanesivan@gmail.com> References: <1476878456-8303-5-git-send-email-matellanesivan@gmail.com> Message-ID: <5c78b656-886a-4ff1-66dc-bf27b4c61093@codeweavers.com> Signed-off-by: Piotr Caban From piotr at codeweavers.com Thu Oct 20 08:59:14 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Thu, 20 Oct 2016 15:59:14 +0200 Subject: [6/6] msvcirt: Implement istrstream constructors In-Reply-To: <1476878456-8303-6-git-send-email-matellanesivan@gmail.com> References: <1476878456-8303-6-git-send-email-matellanesivan@gmail.com> Message-ID: Signed-off-by: Piotr Caban From andrey.goosev at gmail.com Thu Oct 20 08:54:16 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Thu, 20 Oct 2016 16:54:16 +0300 Subject: user32: Add support for WS_EX_RIGHT style. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: user32-Add-support-for-WS_EX_RIGHT-style.patch Type: text/x-patch Size: 1241 bytes Desc: not available URL: From huw at codeweavers.com Thu Oct 20 09:19:44 2016 From: huw at codeweavers.com (Huw Davies) Date: Thu, 20 Oct 2016 15:19:44 +0100 Subject: user32: Add support for WS_EX_RIGHT style. In-Reply-To: References: Message-ID: <20161020141944.GA27445@merlot.physics.ox.ac.uk> Signed-off-by: Huw Davies I tested the BS_LEFTTEXT with WS_EX_RIGHT case and this patch looks good for that too. Huw. From frederic.delanoy at gmail.com Thu Oct 20 09:29:03 2016 From: frederic.delanoy at gmail.com (=?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delanoy?=) Date: Thu, 20 Oct 2016 16:29:03 +0200 Subject: po: Update French translation Message-ID: <20161020142903.13168-1-frederic.delanoy@gmail.com> Signed-off-by: Frédéric Delanoy --- po/fr.po | 159 +++++++++++++++++++++++++++++---------------------------------- 1 file changed, 74 insertions(+), 85 deletions(-) diff --git a/po/fr.po b/po/fr.po index 2b4d291..aefdc4d 100644 --- a/po/fr.po +++ b/po/fr.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: Wine\n" "Report-Msgid-Bugs-To: http://bugs.winehq.org\n" "POT-Creation-Date: N/A\n" -"PO-Revision-Date: 2016-04-19 11:46+0100\n" +"PO-Revision-Date: 2016-10-20 16:19+0100\n" "Last-Translator: Frédéric Delanoy \n" "Language-Team: French\n" "Language: fr\n" @@ -10636,10 +10636,8 @@ msgid "IPv6 address" msgstr "Adresse IPv6" #: msinfo32.rc:28 -#, fuzzy -#| msgid "System Configuration" msgid "System Information" -msgstr "Configuration système" +msgstr "Informations système" #: net.rc:30 msgid "" @@ -11692,6 +11690,15 @@ msgid "" " REG [operation] /?\n" "\n" msgstr "" +"Usage :\n" +" REG [opération] [paramètres]\n" +"\n" +"Opérations prises en charge :\n" +" ADD | DELETE | QUERY\n" +"\n" +"Pour de l'aide sur une opération spécifique, tapez :\n" +" REG [opération] /?\n" +"\n" #: reg.rc:36 msgid "" @@ -11783,7 +11790,7 @@ msgid "" "reg: Unable to delete all registry values in '%1'. An unexpected error " "occurred.\n" msgstr "" -"reg : Impossible d'effacer toutes les valeurs de registre dans « %1 ».Une " +"reg : impossible d'effacer toutes les valeurs de registre dans « %1 ». Une " "erreur inattendue est survenue.\n" #: reg.rc:59 @@ -11791,32 +11798,28 @@ msgid "" "reg: Unable to complete the specified operation. An unexpected error " "occurred.\n" msgstr "" -"reg : Impossible d'effectuer l'opération spécifiée. Une erreur inattendue " +"reg : impossible d'effectuer l'opération spécifiée. Une erreur inattendue " "est survenue.\n" #: reg.rc:60 msgid "Search complete. Number of matches found: %1!d!\n" -msgstr "" +msgstr "Recherche terminée. Nombre de correspondances trouvées : %1!d!\n" #: reg.rc:61 -#, fuzzy -#| msgid "reg: Invalid key name\n" msgid "reg: Invalid syntax. " -msgstr "reg : nom de clé invalide\n" +msgstr "reg : syntaxe invalide. " #: reg.rc:62 -#, fuzzy -#| msgid "uninstaller: Invalid option [%1]\n" msgid "reg: Invalid option [%1]. " -msgstr "uninstaller : option [%1] invalide\n" +msgstr "reg : option [%1] invalide. " #: reg.rc:63 msgid "Type \"REG /?\" for help.\n" -msgstr "" +msgstr "Tapez « REG /? » pour de l'aide.\n" #: reg.rc:64 msgid "Type \"REG %1 /?\" for help.\n" -msgstr "" +msgstr "Tapez « REG %1 /? » pour de l'aide.\n" #: reg.rc:65 regedit.rc:205 msgid "(value not set)" @@ -12063,133 +12066,125 @@ msgid "" " regedit /E \"export.reg\" \"HKEY_CURRENT_USER\\Console\"\n" " regedit /D \"HKEY_LOCAL_MACHINE\\Error\\Path\"\n" msgstr "" +"Usage :\n" +" regedit [options] [nom_fichier] [clé_registre]\n" +"\n" +"Options :\n" +" [pas d'option] Lancer la version graphique de ce programme.\n" +" /L:system.dat L'emplacement du fichier system.dat à modifier.\n" +" Compatible avec toute autre option. Ignorée.\n" +" /R:user.dat L'emplacement du fichier user.dat à modifier.\n" +" Compatible avec toute autre option. Ignorée.\n" +" /C Importer le contenu d'un fichier de registre.\n" +" /D Effacer une clé de registre spécifiée.\n" +" /E Exporter le contenu d'une clé de registre spécifiée dans \n" +" fichier. Si aucune clé n'est spécifiée, le registre entier \n" +" est exporté.\n" +" /S Mode silencieux. Aucun message ne sera affiché.\n" +" /V Lancer l'interface graphique en mode avancé. Ignorée.\n" +" /? Afficher ces informations et se terminer.\n" +" [nom_fichier] L'emplacement du fichier contenant des informations de registre \n" +" à importer.\n" +" Si utilisée avec [/E], cette option spécifie l'emplacement \n" +" du fichier où les informations du registre seront exportées.\n" +" [clé_registre] La clé de registre à modifier.\n" +"\n" +"Exemples d'usage :\n" +" regedit \"import.reg\"\n" +" regedit /E \"export.reg\" \"HKEY_CURRENT_USER\\Console\"\n" +" regedit /D \"HKEY_LOCAL_MACHINE\\Chemin\\Défectueux\"\n" #: regedit.rc:360 -#, fuzzy -#| msgid "" -#| "regsvr32: Invalid or unrecognized switch [%1]\n" -#| "\n" msgid "regedit: Invalid or unrecognized switch [%1]\n" msgstr "" -"regsvr32 : Option [%1] invalide ou non reconnue\n" -"\n" +"regedit : option [%1] invalide ou non reconnue\n" #: regedit.rc:361 msgid "Type \"regedit /?\" for help.\n" -msgstr "" +msgstr "Tapez « regedit /? » pour de l'aide.\n" #: regedit.rc:362 -#, fuzzy -#| msgid "No command was specified." msgid "regedit: No filename was specified.\n" -msgstr "Aucune commande spécifiée." +msgstr "regedit : aucun nom de fichier spécifié.\n" #: regedit.rc:363 msgid "regedit: No registry key was specified for removal.\n" -msgstr "" +msgstr "regedit : aucune clé de registre à supprimer n'a été spécifiée.\n" #: regedit.rc:364 -#, fuzzy -#| msgid "uninstaller: The application with GUID '%1' was not found\n" msgid "regedit: The file '%1' was not found.\n" -msgstr "uninstaller : l'application de GUID « %1 » est introuvable\n" +msgstr "regedit : le fichier « %1 » est introuvable.\n" #: regedit.rc:365 -#, fuzzy -#| msgid "reg: Unable to access remote machine\n" msgid "regedit: Unable to open the file '%1'.\n" -msgstr "reg : impossible d'accéder à une machine distante\n" +msgstr "regedit : impossible d'ouvrir le fichier « %1 ».\n" #: regedit.rc:366 -#, fuzzy -#| msgid "Invalid handle operation.\n" msgid "regedit: Unhandled action.\n" -msgstr "Opération invalide sur un descripteur.\n" +msgstr "regedit : action non gérée.\n" #: regedit.rc:367 msgid "regedit: Out of memory! (%1!S!, line %2!u!)\n" -msgstr "" +msgstr "regedit : mémoire insuffisante ! (%1!S!, ligne %2!u!)\n" #: regedit.rc:368 -#, fuzzy -#| msgid "reg: Invalid key name\n" msgid "regedit: Invalid hexadecimal value.\n" -msgstr "reg : nom de clé invalide\n" +msgstr "regedit : valeur hexadécimale invalide.\n" #: regedit.rc:369 msgid "" "regedit: Unable to convert hexadecimal data. An invalid value was " "encountered at '%1'.\n" msgstr "" +"regedit : impossible de convertir les données hexadécimales. Une " +"valeur invalide a été trouvée dans « %1 ».\n" #: regedit.rc:370 -#, fuzzy -#| msgid "" -#| "regsvr32: Invalid or unrecognized switch [%1]\n" -#| "\n" msgid "regedit: Unrecognized escape sequence [\\%1!c!]\n" msgstr "" -"regsvr32 : Option [%1] invalide ou non reconnue\n" -"\n" +"regedit : séquence d'échappement non reconnue [\\%1!c!]\n" #: regedit.rc:371 -#, fuzzy -#| msgid "reg: Unsupported registry data type [%1]\n" msgid "regedit: Unsupported registry data type [%1]\n" -msgstr "reg : type non pris en charge [%1]\n" +msgstr "regedit : type de données de registre non pris en charge [%1]\n" #: regedit.rc:372 -#, fuzzy -#| msgid "reg: Unable to access remote machine\n" msgid "regedit: Unexpected end of line in '%1'.\n" -msgstr "reg : impossible d'accéder à une machine distante\n" +msgstr "regedit : fin de ligne inattendue dans « %1 ».\n" #: regedit.rc:373 -#, fuzzy -#| msgid "uninstaller: The application with GUID '%1' was not found\n" msgid "regedit: The line '%1' was not recognized.\n" -msgstr "uninstaller : l'application de GUID « %1 » est introuvable\n" +msgstr "regedit : la ligne « %1 » n'a pas été reconnue.\n" #: regedit.rc:374 -#, fuzzy -#| msgid "reg: Unable to access remote machine\n" msgid "regedit: Unable to add the registry value '%1' to '%2'.\n" -msgstr "reg : impossible d'accéder à une machine distante\n" +msgstr "regedit : impossible d'ajouter la valeur de registre « %1 » à « %2 ».\n" #: regedit.rc:375 -#, fuzzy -#| msgid "reg: Unable to access remote machine\n" msgid "regedit: Unable to open the registry key '%1'.\n" -msgstr "reg : impossible d'accéder à une machine distante\n" +msgstr "regedit : impossible d'ouvrir la clé de registre « %1 ».\n" #: regedit.rc:376 -#, fuzzy -#| msgid "reg: Unsupported registry data type [%1]\n" msgid "regedit: Unsupported registry data type [%1] encountered in '%2'.\n" -msgstr "reg : type non pris en charge [%1]\n" +msgstr "regedit : type de données de registre [%1] rencontré dans [%2].\n" #: regedit.rc:377 msgid "regedit: The registry value '%1' will be exported as binary data.\n" -msgstr "" +msgstr "regedit : la valeur de registre « %1 » sera exportée comme donnée binaire.\n" #: regedit.rc:378 msgid "regedit: Incorrect registry class specification in '%1'.\n" -msgstr "" +msgstr "regedit : spécification de classe de registre incorrecte dans « %1 ».\n" #: regedit.rc:379 -#, fuzzy -#| msgid "" -#| "reg: The system was unable to find the specified registry key or value\n" msgid "" "regedit: Unable to export '%1'. The specified registry key was not found.\n" msgstr "" -"reg : le système n'a pas pu trouver la clé ou valeur de registre spécifiée\n" +"regedit : impossible d'exporter « %1 ». La clé de registre spécifiée est introuvable.\n" #: regedit.rc:380 -#, fuzzy -#| msgid "reg: Unable to access remote machine\n" msgid "regedit: Unable to delete the registry class '%1'.\n" -msgstr "reg : impossible d'accéder à une machine distante\n" +msgstr "regedit : impossible d'effacer la classe de registre « %1 ».\n" #: regedit.rc:163 msgid "Quits the registry editor" @@ -14681,10 +14676,8 @@ msgid "Error: Invalid query\n" msgstr "Erreur : requête invalide\n" #: wmic.rc:31 -#, fuzzy -#| msgid "reg: Invalid key name\n" msgid "Error: Invalid syntax for PATH\n" -msgstr "reg : nom de clé invalide\n" +msgstr "Erreur : Syntaxe invalide pour PATH\n" #: wordpad.rc:31 msgid "&New...\tCtrl+N" @@ -14759,36 +14752,32 @@ msgid "F&ormat" msgstr "Forma&t" #: wordpad.rc:85 -#, fuzzy -#| msgid "&List" msgid "&Lists" -msgstr "&Liste" +msgstr "&Listes" #: wordpad.rc:87 wordpad.rc:116 msgid "&Bullet points" msgstr "Pu&ces" #: wordpad.rc:88 -#, fuzzy -#| msgid "CRL Number" msgid "Numbers" -msgstr "Numéro de la LRC" +msgstr "Numéros" #: wordpad.rc:89 msgid "Letters - lower case" -msgstr "" +msgstr "Lettres - minuscules" #: wordpad.rc:90 msgid "Letters - upper case" -msgstr "" +msgstr "Lettres - majuscules" #: wordpad.rc:91 msgid "Roman numerals - lower case" -msgstr "" +msgstr "Chiffres romains - minuscules" #: wordpad.rc:92 msgid "Roman numerals - upper case" -msgstr "" +msgstr "Chiffres romains - majuscules" #: wordpad.rc:94 wordpad.rc:117 msgid "&Paragraph..." -- 2.10.1 From rpisl at seznam.cz Thu Oct 20 13:29:11 2016 From: rpisl at seznam.cz (=?UTF-8?q?Roman=20Pi=C5=A1l?=) Date: Thu, 20 Oct 2016 20:29:11 +0200 Subject: [PATCH] ws2_32: Allow user to enable IP dual stack (v6). Message-ID: <1476988151-21081-1-git-send-email-rpisl@seznam.cz> IP dual stack (v4+v6) should be disabled by default, but previous code was setting IPV6_V6ONLY in bind() which prevented user to override it. This patch moves setting IPV6_V6ONLY to socket creation time. V1..V3 - original version by Matthieu Nottale V4 - modified tests V5 - fixed failing test on Windows V6 - fixed setting of IPV6_V6ONLY in WSASocketW and formatting Signed-off-by: Roman Pišl --- dlls/ws2_32/socket.c | 31 +++++++++++--------- dlls/ws2_32/tests/sock.c | 75 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 88 insertions(+), 18 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 3d9a99b..cdebe41 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3240,20 +3240,6 @@ int WINAPI WS_bind(SOCKET s, const struct WS_sockaddr* name, int namelen) } else { -#ifdef IPV6_V6ONLY - const struct sockaddr_in6 *in6 = (const struct sockaddr_in6*) &uaddr; - if (name->sa_family == WS_AF_INET6 && - !memcmp(&in6->sin6_addr, &in6addr_any, sizeof(struct in6_addr))) - { - int enable = 1; - if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable)) == -1) - { - release_sock_fd( s, fd ); - SetLastError(WSAEAFNOSUPPORT); - return SOCKET_ERROR; - } - } -#endif if (name->sa_family == WS_AF_INET) { struct sockaddr_in *in4 = (struct sockaddr_in*) &uaddr; @@ -7241,6 +7227,23 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, TRACE("\tcreated %04lx\n", ret ); if (ipxptype > 0) set_ipx_packettype(ret, ipxptype); + +#ifdef IPV6_V6ONLY + if (unixaf == AF_INET6) + { + int fd = get_sock_fd(ret, 0, NULL); + if (fd != -1) + { + /* IPV6_V6ONLY is set by default on Windows */ + int enable = 1; + if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable)) != 0) + { + WARN("\tsetting IPV6_V6ONLY failure - errno = %i\n", errno); + } + release_sock_fd(ret, fd); + } + } +#endif return ret; } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index a144bd3..49d4e13 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1732,7 +1732,7 @@ static void test_so_reuseaddr(void) DWORD err; saddr.sin_family = AF_INET; - saddr.sin_port = htons(9375); + saddr.sin_port = htons(SERVERPORT+1); saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); s1=socket(AF_INET, SOCK_STREAM, 0); @@ -6110,6 +6110,8 @@ static void test_ipv6only(void) struct sockaddr_in sin4; struct sockaddr_in6 sin6; int ret; + int enabled; + int len; memset(&sin4, 0, sizeof(sin4)); sin4.sin_family = AF_INET; @@ -6138,9 +6140,74 @@ static void test_ipv6only(void) WSAGetLastError()); goto end; } + + /* bind on IPv4 socket should succeed - IPV6_V6ONLY is enabled by default */ ret = bind(v4, (struct sockaddr*)&sin4, sizeof(sin4)); - ok(!ret, "Could not bind IPv4 address (LastError: %d; %d expected if IPv6 binds to IPv4 as well).\n", - WSAGetLastError(), WSAEADDRINUSE); + ok(!ret, "Could not bind IPv4 address (LastError: %d).\n", + WSAGetLastError()); + + closesocket(v4); + closesocket(v6); + v4 = INVALID_SOCKET; + v6 = INVALID_SOCKET; + + /* Test again, this time disabling IPV6_V6ONLY. */ + sin4.sin_port = htons(SERVERPORT+2); + sin6.sin6_port = htons(SERVERPORT+2); + + v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + ok(v6 != INVALID_SOCKET, "Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n", + WSAGetLastError(), WSAEAFNOSUPPORT); + + enabled = 2; + len = sizeof(enabled); + ret = getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len); + if (ret) + { + skip("Could not check IPV6_V6ONLY (LastError: %d).\n", WSAGetLastError()); + goto end; + } + ok(enabled == 1, "IPV6_V6ONLY is not enabled by default.\n"); + + enabled = 0; + ret = setsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len); + ok(!ret, "Could not disable IPV6_V6ONLY (LastError: %d).\n", WSAGetLastError()); + + /* + Observaition: + On Windows, bind on both IPv4 and IPv6 with IPV6_V6ONLY disabled succeeds by default. + Application must set SO_EXCLUSIVEADDRUSE on first socket to disallow another successful bind. + In general, a standard application should not use SO_REUSEADDR. + Setting both SO_EXCLUSIVEADDRUSE and SO_REUSEADDR on the same socket is not possible in + either order, the later setsockopt call always fails. + */ + enabled = 1; + ret = setsockopt(v6, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&enabled, len); + ok(!ret, "Could not set SO_EXCLUSIVEADDRUSE on IPv6 socket (LastError: %d).\n", + WSAGetLastError()); + + ret = bind(v6, (struct sockaddr*)&sin6, sizeof(sin6)); + ok(!ret, "Could not bind IPv6 address (LastError: %d).\n", WSAGetLastError()); + + enabled = 2; + len = sizeof(enabled); + getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len); + ok(enabled == 0, "IPV6_V6ONLY is enabled after bind.\n"); + + v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + ok(v4 != INVALID_SOCKET, "Could not create IPv4 socket (LastError: %d).\n", + WSAGetLastError()); + + enabled = 1; + ret = setsockopt(v4, SOL_SOCKET, SO_REUSEADDR, (char*)&enabled, len); + ok(!ret, "Could not set SO_REUSEADDR on IPv4 socket (LastError: %d).\n", + WSAGetLastError()); + + WSASetLastError(0xdeadbeef); + bind(v4, (struct sockaddr*)&sin4, sizeof(sin4)); + + ok(WSAGetLastError() == WSAEACCES, "Failed to disable IPV6_V6ONLY (LastError: %d; %d expected if IPv6 binds to IPv4 as well).\n", + WSAGetLastError(), WSAEACCES); end: if (v4 != INVALID_SOCKET) @@ -8024,7 +8091,7 @@ static void test_TransmitFile(void) /* Setup a properly connected socket for transfers */ memset(&bindAddress, 0, sizeof(bindAddress)); bindAddress.sin_family = AF_INET; - bindAddress.sin_port = htons(9375); + bindAddress.sin_port = htons(SERVERPORT+1); bindAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); iret = bind(server, (struct sockaddr*)&bindAddress, sizeof(bindAddress)); if (iret != 0) -- 2.7.4 From ken at codeweavers.com Thu Oct 20 14:31:51 2016 From: ken at codeweavers.com (Ken Thomases) Date: Thu, 20 Oct 2016 14:31:51 -0500 Subject: [PATCH 2/2] kernel32/tests: Test that ConnectNamedPipe() works immediately after DisconnectNamedPipe() without waiting for the client to close. In-Reply-To: <1476991911-10119-1-git-send-email-ken@codeweavers.com> References: <1476991911-10119-1-git-send-email-ken@codeweavers.com> Message-ID: <1476991911-10119-2-git-send-email-ken@codeweavers.com> Signed-off-by: Ken Thomases --- dlls/kernel32/tests/pipe.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c index cf7e3ba..6c311a4 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -2060,6 +2060,20 @@ static DWORD CALLBACK overlapped_server(LPVOID arg) ok(ret == 1, "ret %d\n", ret); DisconnectNamedPipe(pipe); + + ret = ConnectNamedPipe(pipe, &ol); + err = GetLastError(); + ok(ret == 0, "ret %d\n", ret); + ok(err == ERROR_IO_PENDING, "gle %d\n", err); + CancelIo(pipe); + ret = WaitForSingleObjectEx(ol.hEvent, INFINITE, 1); + ok(ret == WAIT_OBJECT_0, "ret %x\n", ret); + + ret = GetOverlappedResult(pipe, &ol, &num, 1); + err = GetLastError(); + ok(ret == 0, "ret %d\n", ret); + ok(err == ERROR_OPERATION_ABORTED, "gle %d\n", err); + CloseHandle(ol.hEvent); CloseHandle(pipe); return 1; -- 2.8.2 From ken at codeweavers.com Thu Oct 20 14:31:50 2016 From: ken at codeweavers.com (Ken Thomases) Date: Thu, 20 Oct 2016 14:31:50 -0500 Subject: [PATCH 1/2] server: Make disconnecting a named pipe immediately close the client's connection and allow the server to initiate a new connection. Message-ID: <1476991911-10119-1-git-send-email-ken@codeweavers.com> Signed-off-by: Ken Thomases --- server/named_pipe.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/server/named_pipe.c b/server/named_pipe.c index cfee4d5..b032901 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -60,7 +60,6 @@ enum pipe_state ps_wait_open, ps_connected_server, ps_wait_disconnect, - ps_disconnected_server, ps_wait_connect }; @@ -344,7 +343,6 @@ static void set_server_state( struct pipe_server *server, enum pipe_state state assert( !server->fd ); set_no_fd_status( server->ioctl_fd, STATUS_PIPE_LISTENING ); break; - case ps_disconnected_server: case ps_wait_connect: assert( !server->fd ); set_no_fd_status( server->ioctl_fd, STATUS_PIPE_DISCONNECTED ); @@ -430,9 +428,6 @@ static void pipe_client_destroy( struct object *obj) do a successful flush without it. */ set_server_state( server, ps_wait_disconnect ); break; - case ps_disconnected_server: - set_server_state( server, ps_wait_connect ); - break; case ps_idle_server: case ps_wait_open: case ps_wait_disconnect: @@ -623,9 +618,6 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a case ps_connected_server: set_error( STATUS_PIPE_CONNECTED ); break; - case ps_disconnected_server: - set_error( STATUS_PIPE_BUSY ); - break; case ps_wait_disconnect: set_error( STATUS_NO_DATA_DETECTED ); break; @@ -644,10 +636,11 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a notify_empty( server ); - /* dump the client and server fds, but keep the pointers - around - client loses all waiting data */ + /* dump the client and server fds - client loses all waiting data */ do_disconnect( server ); - set_server_state( server, ps_disconnected_server ); + server->client->server = NULL; + server->client = NULL; + set_server_state( server, ps_wait_connect ); break; case ps_wait_disconnect: assert( !server->client ); @@ -658,7 +651,6 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a case ps_wait_open: set_error( STATUS_PIPE_LISTENING ); break; - case ps_disconnected_server: case ps_wait_connect: set_error( STATUS_PIPE_DISCONNECTED ); break; -- 2.8.2 From madewokherd at gmail.com Thu Oct 20 15:21:28 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Thu, 20 Oct 2016 15:21:28 -0500 Subject: gdiplus: Implement GdipIsOutlineVisiblePathPoint. Message-ID: <1476994888-703-1-git-send-email-madewokherd@gmail.com> From: Vincent Povirk Signed-off-by: Vincent Povirk --- dlls/gdiplus/graphicspath.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 8ba0016..b6ec88d 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -1581,17 +1581,49 @@ GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPointI(GpPath* path, INT x, INT y, GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPoint(GpPath* path, REAL x, REAL y, GpPen *pen, GpGraphics *graphics, BOOL *result) { - static int calls; + GpStatus stat; + GpPath *wide_path; + GpMatrix *transform = NULL; TRACE("(%p,%0.2f,%0.2f,%p,%p,%p)\n", path, x, y, pen, graphics, result); if(!path || !pen) return InvalidParameter; - if(!(calls++)) - FIXME("not implemented\n"); + stat = GdipClonePath(path, &wide_path); - return NotImplemented; + if (stat != Ok) + return stat; + + if (pen->unit == UnitPixel && graphics != NULL) + { + stat = GdipCreateMatrix(&transform); + + if (stat == Ok) + stat = get_graphics_transform(graphics, CoordinateSpaceDevice, + CoordinateSpaceWorld, transform); + } + + if (stat == Ok) + stat = GdipWidenPath(wide_path, pen, transform, 1.0); + + if (pen->unit == UnitPixel && graphics != NULL) + { + if (stat == Ok) + stat = GdipInvertMatrix(transform); + + if (stat == Ok) + stat = GdipTransformPath(wide_path, transform); + } + + if (stat == Ok) + stat = GdipIsVisiblePathPoint(wide_path, x, y, graphics, result); + + GdipDeleteMatrix(transform); + + GdipDeletePath(wide_path); + + return stat; } GpStatus WINGDIPAPI GdipIsVisiblePathPointI(GpPath* path, INT x, INT y, GpGraphics *graphics, BOOL *result) -- 2.7.4 From aric at codeweavers.com Thu Oct 20 22:58:47 2016 From: aric at codeweavers.com (Aric Stewart) Date: Fri, 21 Oct 2016 05:58:47 +0200 Subject: [PATCH] hidclass.sys: Watch return for STATUS_PENDING not IRP status Message-ID: Signed-off-by: Aric Stewart --- dlls/hidclass.sys/main.c | 4 ++-- dlls/hidclass.sys/pnp.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-hidclass.sys-Watch-return-for-STATUS_PENDING-not-IRP-s.txt Type: text/x-patch Size: 1273 bytes Desc: not available URL: From aric at codeweavers.com Thu Oct 20 23:15:38 2016 From: aric at codeweavers.com (Aric Stewart) Date: Fri, 21 Oct 2016 06:15:38 +0200 Subject: [PATCH v3] hid/tests: Add HID device enumeration test Message-ID: v2: Suggestions from Sebastian Lackner v3: Further suggestions from Sebastian Lackner Signed-off-by: Aric Stewart --- configure | 1 + configure.ac | 1 + dlls/hid/tests/Makefile.in | 5 +++ dlls/hid/tests/device.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+) create mode 100644 dlls/hid/tests/Makefile.in create mode 100644 dlls/hid/tests/device.c -------------- next part -------------- A non-text attachment was scrubbed... Name: v3-0001-hid-tests-Add-HID-device-enumeration-test.txt Type: text/x-patch Size: 4575 bytes Desc: not available URL: From hverbeet at codeweavers.com Fri Oct 21 06:15:23 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 21 Oct 2016 13:15:23 +0200 Subject: [PATCH 1/9] wined3d: Introduce wined3d_buffer_prepapre_location(). In-Reply-To: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-1-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 21 06:15:24 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 21 Oct 2016 13:15:24 +0200 Subject: [PATCH 3/9] wined3d: Do not assume that WINED3D_LOCATION_SYSMEM is always valid for double buffered buffers. In-Reply-To: <1476960658-29001-3-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-3-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 21 06:15:25 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 21 Oct 2016 13:15:25 +0200 Subject: [PATCH 2/9] wined3d: Introduce wined3d_buffer_load_location(). In-Reply-To: <1476960658-29001-2-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-2-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 21 06:15:26 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 21 Oct 2016 13:15:26 +0200 Subject: [PATCH 4/9] wined3d: Move buffer_get_memory() under wined3d_buffer_load_sysmem(). In-Reply-To: <1476960658-29001-4-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-4-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 21 06:15:27 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 21 Oct 2016 13:15:27 +0200 Subject: [PATCH 5/9] wined3d: Implement wined3d_buffer_prepare_location() for WINED3D_LOCATION_BUFFER. In-Reply-To: <1476960658-29001-5-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-5-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 21 06:15:28 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 21 Oct 2016 13:15:28 +0200 Subject: [PATCH 8/9] wined3d: Introduce wined3d_buffer_get_memory(). In-Reply-To: <1476960658-29001-8-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-8-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 21 06:15:29 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 21 Oct 2016 13:15:29 +0200 Subject: [PATCH 9/9] wined3d: Prefer current locations to WINED3D_LOCATION_SYSMEM in wined3d_buffer_copy(). In-Reply-To: <1476960658-29001-9-git-send-email-jkucia@codeweavers.com> References: <1476960658-29001-9-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From aeikum at codeweavers.com Fri Oct 21 11:28:49 2016 From: aeikum at codeweavers.com (Andrew Eikum) Date: Fri, 21 Oct 2016 11:28:49 -0500 Subject: [PATCH 1/4] d2d1: Implement FillContainsPoint for rectangles Message-ID: <20161021162849.GZ7470@foghorn.codeweavers.com> Signed-off-by: Andrew Eikum --- dlls/d2d1/d2d1_private.h | 21 +++++++++++++++++++++ dlls/d2d1/geometry.c | 24 ++++++++++++++++++++++-- dlls/d2d1/render_target.c | 6 ------ 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index b49fce4..c80a14d 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -357,4 +357,25 @@ static inline void d2d_matrix_multiply(D2D_MATRIX_3X2_F *a, const D2D_MATRIX_3X2 a->_32 = tmp._31 * b->_12 + tmp._32 * b->_22 + b->_32; } +static inline void d2d_point_transform(D2D1_POINT_2F *dst, const D2D1_MATRIX_3X2_F *matrix, float x, float y) +{ + dst->x = x * matrix->_11 + y * matrix->_21 + matrix->_31; + dst->y = x * matrix->_12 + y * matrix->_22 + matrix->_32; +} + +/* dst must be different from src */ +static inline BOOL d2d_matrix_invert(D2D_MATRIX_3X2_F *dst, const D2D_MATRIX_3X2_F *src) +{ + float d = src->_11 * src->_22 - src->_21 * src->_12; + if (d == 0.0f) + return FALSE; + dst->_11 = src->_22 / d; + dst->_21 = -src->_21 / d; + dst->_31 = (src->_21 * src->_32 - src->_31 * src->_22) / d; + dst->_12 = -src->_12 / d; + dst->_22 = src->_11 / d; + dst->_32 = -(src->_11 * src->_32 - src->_31 * src->_12) / d; + return TRUE; +} + #endif /* __WINE_D2D1_PRIVATE_H */ diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c index 9fa1783..eba9911 100644 --- a/dlls/d2d1/geometry.c +++ b/dlls/d2d1/geometry.c @@ -2374,10 +2374,30 @@ static HRESULT STDMETHODCALLTYPE d2d_rectangle_geometry_StrokeContainsPoint(ID2D static HRESULT STDMETHODCALLTYPE d2d_rectangle_geometry_FillContainsPoint(ID2D1RectangleGeometry *iface, D2D1_POINT_2F point, const D2D1_MATRIX_3X2_F *transform, float tolerance, BOOL *contains) { - FIXME("iface %p, point {%.8e, %.8e}, transform %p, tolerance %.8e, contains %p stub!\n", + struct d2d_geometry *geometry = impl_from_ID2D1RectangleGeometry(iface); + D2D1_MATRIX_3X2_F g_i; + D2D1_POINT_2F probe; + + TRACE("iface %p, point {%.8e, %.8e}, transform %p, tolerance %.8e, contains %p\n", iface, point.x, point.y, transform, tolerance, contains); - return E_NOTIMPL; + if (transform) + { + if (!d2d_matrix_invert(&g_i, transform)) + return D2DERR_UNSUPPORTED_OPERATION; + d2d_point_transform(&probe, &g_i, point.x, point.y); + } + else + probe = point; + + *contains = probe.x > geometry->u.rectangle.rect.left - tolerance && + probe.x < geometry->u.rectangle.rect.right + tolerance && + probe.y > geometry->u.rectangle.rect.top - tolerance && + probe.y < geometry->u.rectangle.rect.bottom + tolerance; + + TRACE("-> %#x\n", *contains); + + return S_OK; } static HRESULT STDMETHODCALLTYPE d2d_rectangle_geometry_CompareWithGeometry(ID2D1RectangleGeometry *iface, diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index bc31f4d..798dd0d 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -48,12 +48,6 @@ static void d2d_point_set(D2D1_POINT_2F *dst, float x, float y) dst->y = y; } -static void d2d_point_transform(D2D1_POINT_2F *dst, const D2D1_MATRIX_3X2_F *matrix, float x, float y) -{ - dst->x = x * matrix->_11 + y * matrix->_21 + matrix->_31; - dst->y = x * matrix->_12 + y * matrix->_22 + matrix->_32; -} - static void d2d_rect_expand(D2D1_RECT_F *dst, const D2D1_POINT_2F *point) { if (point->x < dst->left) -- 2.10.0 From aeikum at codeweavers.com Fri Oct 21 11:28:53 2016 From: aeikum at codeweavers.com (Andrew Eikum) Date: Fri, 21 Oct 2016 11:28:53 -0500 Subject: [PATCH 2/4] d2d1: Implement FillContainsPoint for paths Message-ID: <20161021162853.GA7470@foghorn.codeweavers.com> Signed-off-by: Andrew Eikum --- dlls/d2d1/geometry.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c index eba9911..eb4f98e 100644 --- a/dlls/d2d1/geometry.c +++ b/dlls/d2d1/geometry.c @@ -1924,9 +1924,11 @@ static HRESULT STDMETHODCALLTYPE d2d_geometry_sink_Close(ID2D1GeometrySink *ifac } done: - d2d_path_geometry_free_figures(geometry); if (FAILED(hr)) + { + d2d_path_geometry_free_figures(geometry); geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR; + } return hr; } @@ -2112,10 +2114,27 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_StrokeContainsPoint(ID2D1Path static HRESULT STDMETHODCALLTYPE d2d_path_geometry_FillContainsPoint(ID2D1PathGeometry *iface, D2D1_POINT_2F point, const D2D1_MATRIX_3X2_F *transform, float tolerance, BOOL *contains) { - FIXME("iface %p, point {%.8e, %.8e}, transform %p, tolerance %.8e, contains %p stub!\n", + struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry(iface); + D2D1_MATRIX_3X2_F g_i; + D2D1_POINT_2F probe; + + TRACE("iface %p, point {%.8e, %.8e}, transform %p, tolerance %.8e, contains %p\n", iface, point.x, point.y, transform, tolerance, contains); - return E_NOTIMPL; + if (transform) + { + if (!d2d_matrix_invert(&g_i, transform)) + return D2DERR_UNSUPPORTED_OPERATION; + d2d_point_transform(&probe, &g_i, point.x, point.y); + } + else + probe = point; + + *contains = !!d2d_path_geometry_point_inside(geometry, &probe); + + TRACE("-> %#x\n", *contains); + + return S_OK; } static HRESULT STDMETHODCALLTYPE d2d_path_geometry_CompareWithGeometry(ID2D1PathGeometry *iface, -- 2.10.0 From aeikum at codeweavers.com Fri Oct 21 11:28:56 2016 From: aeikum at codeweavers.com (Andrew Eikum) Date: Fri, 21 Oct 2016 11:28:56 -0500 Subject: [PATCH 3/4] d2d1: Implement FillContainsPoint for transformed geometries Message-ID: <20161021162856.GB7470@foghorn.codeweavers.com> Signed-off-by: Andrew Eikum --- dlls/d2d1/geometry.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c index eb4f98e..a98651a 100644 --- a/dlls/d2d1/geometry.c +++ b/dlls/d2d1/geometry.c @@ -2666,10 +2666,18 @@ static HRESULT STDMETHODCALLTYPE d2d_transformed_geometry_StrokeContainsPoint(ID static HRESULT STDMETHODCALLTYPE d2d_transformed_geometry_FillContainsPoint(ID2D1TransformedGeometry *iface, D2D1_POINT_2F point, const D2D1_MATRIX_3X2_F *transform, float tolerance, BOOL *contains) { - FIXME("iface %p, point {%.8e, %.8e}, transform %p, tolerance %.8e, contains %p stub!\n", + struct d2d_geometry *geometry = impl_from_ID2D1TransformedGeometry(iface); + D2D1_MATRIX_3X2_F g; + + TRACE("iface %p, point {%.8e, %.8e}, transform %p, tolerance %.8e, contains %p\n", iface, point.x, point.y, transform, tolerance, contains); - return E_NOTIMPL; + g = geometry->transform; + if (transform) + d2d_matrix_multiply(&g, transform); + + return ID2D1Geometry_FillContainsPoint(geometry->u.transformed.src_geometry, + point, &g, tolerance, contains); } static HRESULT STDMETHODCALLTYPE d2d_transformed_geometry_CompareWithGeometry(ID2D1TransformedGeometry *iface, -- 2.10.0 From aeikum at codeweavers.com Fri Oct 21 11:29:00 2016 From: aeikum at codeweavers.com (Andrew Eikum) Date: Fri, 21 Oct 2016 11:29:00 -0500 Subject: [PATCH 4/4] d2d1/tests: Add FillContainsPoint tests Message-ID: <20161021162900.GC7470@foghorn.codeweavers.com> Signed-off-by: Andrew Eikum --- dlls/d2d1/tests/d2d1.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index d9d240c..087de6c 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -1318,7 +1318,7 @@ static void test_path_geometry(void) UINT32 count; HWND window; HRESULT hr; - BOOL match; + BOOL match, contains; if (!(device = create_device())) { @@ -1537,6 +1537,32 @@ static void test_path_geometry(void) ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr); match = compare_surface(surface, "3aace1b22aae111cb577614fed16e4eb1650dba5"); ok(match, "Surface does not match.\n"); + + /* edge test */ + set_point(&point, 94.0f, 620.0f); + contains = TRUE; + hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, + point, NULL, 0.0f, &contains); + ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr); + ok(contains == FALSE, "Geometry should not have contained {94, 620}\n"); + + set_point(&point, 95.0f, 620.0f); + contains = FALSE; + hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, + point, NULL, 0.0f, &contains); + ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr); + ok(contains == TRUE, "Geometry should've contained {95, 620}\n"); + + /* with transform matrix */ + set_matrix_identity(&matrix); + translate_matrix(&matrix, -10.0f, 0.0f); + set_point(&point, 85.0f, 620.0f); + contains = FALSE; + hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, + point, &matrix, 0.0f, &contains); + ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr); + ok(contains == TRUE, "Translated geometry should've contained {85, 620}\n"); + ID2D1TransformedGeometry_Release(transformed_geometry); ID2D1PathGeometry_Release(geometry); -- 2.10.0 From matellanesivan at gmail.com Fri Oct 21 12:34:01 2016 From: matellanesivan at gmail.com (=?UTF-8?q?Iv=C3=A1n=20Matellanes?=) Date: Fri, 21 Oct 2016 19:34:01 +0200 Subject: [1/4] msvcirt: Add a partial implementation of class strstream. Message-ID: <1477071244-13290-1-git-send-email-matellanesivan@gmail.com> Signed-off-by: Iván Matellanes --- dlls/msvcirt/msvcirt.c | 69 +++++++++++++++++++++++++++++++++++++++++++++ dlls/msvcirt/msvcirt.spec | 46 +++++++++++++++--------------- dlls/msvcrt20/msvcrt20.spec | 46 +++++++++++++++--------------- dlls/msvcrt40/msvcrt40.spec | 46 +++++++++++++++--------------- 4 files changed, 138 insertions(+), 69 deletions(-) diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index c210862..99388fe 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -195,6 +195,8 @@ extern const vtable_ptr MSVCP_istream_withassign_vtable; extern const vtable_ptr MSVCP_istrstream_vtable; /* ??_7iostream@@6B@ */ extern const vtable_ptr MSVCP_iostream_vtable; +/* ??_7strstream@@6B@ */ +extern const vtable_ptr MSVCP_strstream_vtable; #ifndef __GNUC__ void __asm_dummy_vtables(void) { @@ -263,6 +265,8 @@ void __asm_dummy_vtables(void) { VTABLE_ADD_FUNC(istream_vector_dtor)); __ASM_VTABLE(iostream, VTABLE_ADD_FUNC(iostream_vector_dtor)); + __ASM_VTABLE(strstream, + VTABLE_ADD_FUNC(iostream_vector_dtor)); #ifndef __GNUC__ } #endif @@ -279,8 +283,10 @@ const int ostream_vbtable[] = {0, VBTABLE_ENTRY(ostream, FIELD_OFFSET(ostream, v /* ??_8istrstream@@7B@ */ const int istream_vbtable[] = {0, VBTABLE_ENTRY(istream, FIELD_OFFSET(istream, vbtable), ios)}; /* ??_8iostream@@7Bistream@@@ */ +/* ??_8strstream@@7Bistream@@@ */ const int iostream_vbtable_istream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base1), ios)}; /* ??_8iostream@@7Bostream@@@ */ +/* ??_8strstream@@7Bostream@@@ */ const int iostream_vbtable_ostream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base2), ios)}; DEFINE_RTTI_DATA0(streambuf, 0, ".?AVstreambuf@@") @@ -301,6 +307,9 @@ DEFINE_RTTI_DATA2(istrstream, sizeof(istream), DEFINE_RTTI_DATA4(iostream, sizeof(iostream), &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AViostream@@") +DEFINE_RTTI_DATA4(strstream, sizeof(iostream), + &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, + &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVstrstream@@") /* ?cin@@3Vistream_withassign@@A */ struct { @@ -4129,6 +4138,8 @@ iostream* __thiscall iostream_copy_ctor(iostream *this, const iostream *copy, BO /* ??1iostream@@UAE at XZ */ /* ??1iostream@@UEAA at XZ */ +/* ??1strstream@@UAE at XZ */ +/* ??1strstream@@UEAA at XZ */ DEFINE_THISCALL_WRAPPER(iostream_dtor, 4) void __thiscall iostream_dtor(ios *base) { @@ -4153,6 +4164,8 @@ iostream* __thiscall iostream_assign_sb(iostream *this, streambuf *sb) /* ??4iostream@@IAEAAV0 at AAV0@@Z */ /* ??4iostream@@IEAAAEAV0 at AEAV0@@Z */ +/* ??4strstream@@QAEAAV0 at ABV0@@Z */ +/* ??4strstream@@QEAAAEAV0 at AEBV0@@Z */ DEFINE_THISCALL_WRAPPER(iostream_assign, 8) iostream* __thiscall iostream_assign(iostream *this, const iostream *rhs) { @@ -4161,6 +4174,8 @@ iostream* __thiscall iostream_assign(iostream *this, const iostream *rhs) /* ??_Diostream@@QAEXXZ */ /* ??_Diostream@@QEAAXXZ */ +/* ??_Dstrstream@@QAEXXZ */ +/* ??_Dstrstream@@QEAAXXZ */ DEFINE_THISCALL_WRAPPER(iostream_vbase_dtor, 4) void __thiscall iostream_vbase_dtor(iostream *this) { @@ -4173,6 +4188,7 @@ void __thiscall iostream_vbase_dtor(iostream *this) } /* ??_Eiostream@@UAEPAXI at Z */ +/* ??_Estrstream@@UAEPAXI at Z */ DEFINE_THISCALL_WRAPPER(iostream_vector_dtor, 8) iostream* __thiscall iostream_vector_dtor(ios *base, unsigned int flags) { @@ -4196,6 +4212,7 @@ iostream* __thiscall iostream_vector_dtor(ios *base, unsigned int flags) } /* ??_Giostream@@UAEPAXI at Z */ +/* ??_Gstrstream@@UAEPAXI at Z */ DEFINE_THISCALL_WRAPPER(iostream_scalar_dtor, 8) iostream* __thiscall iostream_scalar_dtor(ios *base, unsigned int flags) { @@ -4208,6 +4225,57 @@ iostream* __thiscall iostream_scalar_dtor(ios *base, unsigned int flags) return this; } +/* ??0strstream@@QAE at ABV0@@Z */ +/* ??0strstream@@QEAA at AEBV0@@Z */ +DEFINE_THISCALL_WRAPPER(strstream_copy_ctor, 12) +iostream* __thiscall strstream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init) +{ + FIXME("(%p %p %d) stub\n", this, copy, virt_init); + return this; +} + +/* ??0strstream@@QAE at PADHH@Z */ +/* ??0strstream@@QEAA at PEADHH@Z */ +DEFINE_THISCALL_WRAPPER(strstream_buffer_ctor, 20) +iostream* __thiscall strstream_buffer_ctor(iostream *this, char *buffer, int length, int mode, BOOL virt_init) +{ + FIXME("(%p %p %d %d %d) stub\n", this, buffer, length, mode, virt_init); + return this; +} + +/* ??0strstream@@QAE at XZ */ +/* ??0strstream@@QEAA at XZ */ +DEFINE_THISCALL_WRAPPER(strstream_ctor, 8) +iostream* __thiscall strstream_ctor(iostream *this, BOOL virt_init) +{ + FIXME("(%p %d) stub\n", this, virt_init); + return this; +} + +/* ?pcount at strstream@@QBEHXZ */ +/* ?pcount at strstream@@QEBAHXZ */ +DEFINE_THISCALL_WRAPPER(strstream_pcount, 4) +int __thiscall strstream_pcount(const iostream *this) +{ + return streambuf_out_waiting(istream_get_ios(&this->base1)->sb); +} + +/* ?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ */ +/* ?rdbuf at strstream@@QEBAPEAVstrstreambuf@@XZ */ +DEFINE_THISCALL_WRAPPER(strstream_rdbuf, 4) +strstreambuf* __thiscall strstream_rdbuf(const iostream *this) +{ + return (strstreambuf*) istream_get_ios(&this->base1)->sb; +} + +/* ?str at strstream@@QAEPADXZ */ +/* ?str at strstream@@QEAAPEADXZ */ +DEFINE_THISCALL_WRAPPER(strstream_str, 4) +char* __thiscall strstream_str(iostream *this) +{ + return strstreambuf_str(strstream_rdbuf(this)); +} + /* ??0Iostream_init@@QAE at AAVios@@H at Z */ /* ??0Iostream_init@@QEAA at AEAVios@@H at Z */ DEFINE_THISCALL_WRAPPER(Iostream_init_ios_ctor, 12) @@ -4363,6 +4431,7 @@ static void init_io(void *base) init_istream_withassign_rtti(base); init_istrstream_rtti(base); init_iostream_rtti(base); + init_strstream_rtti(base); #endif if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) { diff --git a/dlls/msvcirt/msvcirt.spec b/dlls/msvcirt/msvcirt.spec index 598d42a..557185d 100644 --- a/dlls/msvcirt/msvcirt.spec +++ b/dlls/msvcirt/msvcirt.spec @@ -112,12 +112,12 @@ @ cdecl -arch=win64 ??0streambuf@@IEAA at XZ(ptr) streambuf_ctor @ thiscall -arch=win32 ??0streambuf@@QAE at ABV0@@Z(ptr ptr) streambuf_copy_ctor @ cdecl -arch=win64 ??0streambuf@@QEAA at AEBV0@@Z(ptr ptr) streambuf_copy_ctor -@ stub -arch=win32 ??0strstream@@QAE at ABV0@@Z # __thiscall strstream::strstream(class strstream const &) -@ stub -arch=win64 ??0strstream@@QEAA at AEBV0@@Z -@ stub -arch=win32 ??0strstream@@QAE at PADHH@Z # __thiscall strstream::strstream(char *,int,int) -@ stub -arch=win64 ??0strstream@@QEAA at PEADHH@Z -@ stub -arch=win32 ??0strstream@@QAE at XZ # __thiscall strstream::strstream(void) -@ stub -arch=win64 ??0strstream@@QEAA at XZ +@ thiscall -arch=win32 ??0strstream@@QAE at ABV0@@Z(ptr ptr long) strstream_copy_ctor +@ cdecl -arch=win64 ??0strstream@@QEAA at AEBV0@@Z(ptr ptr long) strstream_copy_ctor +@ thiscall -arch=win32 ??0strstream@@QAE at PADHH@Z(ptr ptr long long long) strstream_buffer_ctor +@ cdecl -arch=win64 ??0strstream@@QEAA at PEADHH@Z(ptr ptr long long long) strstream_buffer_ctor +@ thiscall -arch=win32 ??0strstream@@QAE at XZ(ptr long) strstream_ctor +@ cdecl -arch=win64 ??0strstream@@QEAA at XZ(ptr long) strstream_ctor @ thiscall -arch=win32 ??0strstreambuf@@QAE at ABV0@@Z(ptr ptr) strstreambuf_copy_ctor @ cdecl -arch=win64 ??0strstreambuf@@QEAA at AEBV0@@Z(ptr ptr) strstreambuf_copy_ctor @ thiscall -arch=win32 ??0strstreambuf@@QAE at H@Z(ptr long) strstreambuf_dynamic_ctor @@ -166,8 +166,8 @@ @ stub -arch=win64 ??1stdiostream@@UEAA at XZ @ thiscall -arch=win32 ??1streambuf@@UAE at XZ(ptr) streambuf_dtor @ cdecl -arch=win64 ??1streambuf@@UEAA at XZ(ptr) streambuf_dtor -@ stub -arch=win32 ??1strstream@@UAE at XZ # virtual __thiscall strstream::~strstream(void) -@ stub -arch=win64 ??1strstream@@UEAA at XZ +@ thiscall -arch=win32 ??1strstream@@UAE at XZ(ptr) iostream_dtor +@ cdecl -arch=win64 ??1strstream@@UEAA at XZ(ptr) iostream_dtor @ thiscall -arch=win32 ??1strstreambuf@@UAE at XZ(ptr) strstreambuf_dtor @ cdecl -arch=win64 ??1strstreambuf@@UEAA at XZ(ptr) strstreambuf_dtor @ thiscall -arch=win32 ??4Iostream_init@@QAEAAV0 at ABV0@@Z(ptr ptr) Iostream_init_assign @@ -220,8 +220,8 @@ @ stub -arch=win64 ??4stdiostream@@QEAAAEAV0 at AEAV0@@Z @ thiscall -arch=win32 ??4streambuf@@QAEAAV0 at ABV0@@Z(ptr ptr) streambuf_assign @ cdecl -arch=win64 ??4streambuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) streambuf_assign -@ stub -arch=win32 ??4strstream@@QAEAAV0 at AAV0@@Z # class strstream & __thiscall strstream::operator=(class strstream &) -@ stub -arch=win64 ??4strstream@@QEAAAEAV0 at AEAV0@@Z +@ thiscall -arch=win32 ??4strstream@@QAEAAV0 at AAV0@@Z(ptr ptr) iostream_assign +@ cdecl -arch=win64 ??4strstream@@QEAAAEAV0 at AEAV0@@Z(ptr ptr) iostream_assign @ thiscall -arch=win32 ??4strstreambuf@@QAEAAV0 at ABV0@@Z(ptr ptr) strstreambuf_assign @ cdecl -arch=win64 ??4strstreambuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) strstreambuf_assign @ thiscall -arch=win32 ??5istream@@QAEAAV0 at AAC@Z(ptr ptr) istream_read_char @@ -319,7 +319,7 @@ @ extern ??_7stdiobuf@@6B@ MSVCP_stdiobuf_vtable # @ extern ??_7stdiostream@@6B@ # const stdiostream::`vftable' @ extern ??_7streambuf@@6B@ MSVCP_streambuf_vtable -# @ extern ??_7strstream@@6B@ # const strstream::`vftable' +@ extern ??_7strstream@@6B@ MSVCP_strstream_vtable @ extern ??_7strstreambuf@@6B@ MSVCP_strstreambuf_vtable # @ extern ??_8fstream@@7Bistream@@@ # const fstream::`vbtable'{for `istream'} # @ extern ??_8fstream@@7Bostream@@@ # const fstream::`vbtable'{for `ostream'} @@ -335,8 +335,8 @@ @ extern ??_8ostrstream@@7B@ ostream_vbtable # @ extern ??_8stdiostream@@7Bistream@@@ # const stdiostream::`vbtable'{for `istream'} # @ extern ??_8stdiostream@@7Bostream@@@ # const stdiostream::`vbtable'{for `ostream'} -# @ extern ??_8strstream@@7Bistream@@@ # const strstream::`vbtable'{for `istream'} -# @ extern ??_8strstream@@7Bostream@@@ # const strstream::`vbtable'{for `ostream'} +@ extern ??_8strstream@@7Bistream@@@ iostream_vbtable_istream +@ extern ??_8strstream@@7Bostream@@@ iostream_vbtable_ostream @ stub -arch=win32 ??_Dfstream@@QAEXXZ # void __thiscall fstream::`vbase destructor'(void) @ stub -arch=win64 ??_Dfstream@@QEAAXXZ @ stub -arch=win32 ??_Difstream@@QAEXXZ # void __thiscall ifstream::`vbase destructor'(void) @@ -359,8 +359,8 @@ @ cdecl -arch=win64 ??_Dostrstream@@QEAAXXZ(ptr) ostream_vbase_dtor @ stub -arch=win32 ??_Dstdiostream@@QAEXXZ # void __thiscall stdiostream::`vbase destructor'(void) @ stub -arch=win64 ??_Dstdiostream@@QEAAXXZ -@ stub -arch=win32 ??_Dstrstream@@QAEXXZ # void __thiscall strstream::`vbase destructor'(void) -@ stub -arch=win64 ??_Dstrstream@@QEAAXXZ +@ thiscall -arch=win32 ??_Dstrstream@@QAEXXZ(ptr) iostream_vbase_dtor +@ cdecl -arch=win64 ??_Dstrstream@@QEAAXXZ(ptr) iostream_vbase_dtor @ thiscall -arch=win32 ??_Eexception@@UAEPAXI at Z(ptr long) MSVCP_exception_vector_dtor @ thiscall -arch=win32 ??_Efilebuf@@UAEPAXI at Z(ptr long) filebuf_vector_dtor @ stub -arch=win32 ??_Efstream@@UAEPAXI at Z # virtual void * __thiscall fstream::`vector deleting destructor'(unsigned int) @@ -378,7 +378,7 @@ @ thiscall -arch=win32 ??_Estdiobuf@@UAEPAXI at Z(ptr long) stdiobuf_vector_dtor @ stub -arch=win32 ??_Estdiostream@@UAEPAXI at Z # virtual void * __thiscall stdiostream::`vector deleting destructor'(unsigned int) @ thiscall -arch=win32 ??_Estreambuf@@UAEPAXI at Z(ptr long) streambuf_vector_dtor -@ stub -arch=win32 ??_Estrstream@@UAEPAXI at Z # virtual void * __thiscall strstream::`vector deleting destructor'(unsigned int) +@ thiscall -arch=win32 ??_Estrstream@@UAEPAXI at Z(ptr long) iostream_vector_dtor @ thiscall -arch=win32 ??_Estrstreambuf@@UAEPAXI at Z(ptr long) strstreambuf_vector_dtor @ thiscall -arch=win32 ??_Gexception@@UAEPAXI at Z(ptr long) MSVCP_exception_scalar_dtor @ thiscall -arch=win32 ??_Gfilebuf@@UAEPAXI at Z(ptr long) filebuf_scalar_dtor @@ -397,7 +397,7 @@ @ thiscall -arch=win32 ??_Gstdiobuf@@UAEPAXI at Z(ptr long) stdiobuf_scalar_dtor @ stub -arch=win32 ??_Gstdiostream@@UAEPAXI at Z # virtual void * __thiscall stdiostream::`scalar deleting destructor'(unsigned int) @ thiscall -arch=win32 ??_Gstreambuf@@UAEPAXI at Z(ptr long) streambuf_scalar_dtor -@ stub -arch=win32 ??_Gstrstream@@UAEPAXI at Z # virtual void * __thiscall strstream::`scalar deleting destructor'(unsigned int) +@ thiscall -arch=win32 ??_Gstrstream@@UAEPAXI at Z(ptr long) iostream_scalar_dtor @ thiscall -arch=win32 ??_Gstrstreambuf@@UAEPAXI at Z(ptr long) strstreambuf_scalar_dtor @ extern ?adjustfield at ios@@2JB ios_adjustfield @ thiscall -arch=win32 ?allocate at streambuf@@IAEHXZ(ptr) streambuf_allocate @@ -593,8 +593,8 @@ @ cdecl -arch=win64 ?pbump at streambuf@@IEAAXH at Z(ptr long) streambuf_pbump @ thiscall -arch=win32 ?pcount at ostrstream@@QBEHXZ(ptr) ostrstream_pcount @ cdecl -arch=win64 ?pcount at ostrstream@@QEBAHXZ(ptr) ostrstream_pcount -@ stub -arch=win32 ?pcount at strstream@@QBEHXZ # int __thiscall strstream::pcount(void)const -@ stub -arch=win64 ?pcount at strstream@@QEBAHXZ +@ thiscall -arch=win32 ?pcount at strstream@@QBEHXZ(ptr) strstream_pcount +@ cdecl -arch=win64 ?pcount at strstream@@QEBAHXZ(ptr) strstream_pcount @ thiscall -arch=win32 ?peek at istream@@QAEHXZ(ptr) istream_peek @ cdecl -arch=win64 ?peek at istream@@QEAAHXZ(ptr) istream_peek @ thiscall -arch=win32 ?pptr at streambuf@@IBEPADXZ(ptr) streambuf_pptr @@ -627,8 +627,8 @@ @ cdecl -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) ostrstream_rdbuf @ stub -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ # class stdiobuf * __thiscall stdiostream::rdbuf(void)const @ stub -arch=win64 ?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ -@ stub -arch=win32 ?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ # class strstreambuf * __thiscall strstream::rdbuf(void)const -@ stub -arch=win64 ?rdbuf at strstream@@QEBAPEAVstrstreambuf@@XZ +@ thiscall -arch=win32 ?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ(ptr) strstream_rdbuf +@ cdecl -arch=win64 ?rdbuf at strstream@@QEBAPEAVstrstreambuf@@XZ(ptr) strstream_rdbuf @ thiscall -arch=win32 ?rdstate at ios@@QBEHXZ(ptr) ios_rdstate @ cdecl -arch=win64 ?rdstate at ios@@QEBAHXZ(ptr) ios_rdstate @ thiscall -arch=win32 ?read at istream@@QAEAAV1 at PACH@Z(ptr ptr long) istream_read @@ -716,8 +716,8 @@ @ cdecl -arch=win64 ?str at istrstream@@QEAAPEADXZ(ptr) istrstream_str @ thiscall -arch=win32 ?str at ostrstream@@QAEPADXZ(ptr) ostrstream_str @ cdecl -arch=win64 ?str at ostrstream@@QEAAPEADXZ(ptr) ostrstream_str -@ stub -arch=win32 ?str at strstream@@QAEPADXZ # char * __thiscall strstream::str(void) -@ stub -arch=win64 ?str at strstream@@QEAAPEADXZ +@ thiscall -arch=win32 ?str at strstream@@QAEPADXZ(ptr) strstream_str +@ cdecl -arch=win64 ?str at strstream@@QEAAPEADXZ(ptr) strstream_str @ thiscall -arch=win32 ?str at strstreambuf@@QAEPADXZ(ptr) strstreambuf_str @ cdecl -arch=win64 ?str at strstreambuf@@QEAAPEADXZ(ptr) strstreambuf_str @ extern ?sunk_with_stdio at ios@@0HA ios_sunk_with_stdio diff --git a/dlls/msvcrt20/msvcrt20.spec b/dlls/msvcrt20/msvcrt20.spec index 584a85e..4059a47 100644 --- a/dlls/msvcrt20/msvcrt20.spec +++ b/dlls/msvcrt20/msvcrt20.spec @@ -102,12 +102,12 @@ @ cdecl -arch=win64 ??0streambuf@@IEAA at XZ(ptr) msvcirt.??0streambuf@@IEAA at XZ @ thiscall -arch=win32 ??0streambuf@@QAE at ABV0@@Z(ptr ptr) msvcirt.??0streambuf@@QAE at ABV0@@Z @ cdecl -arch=win64 ??0streambuf@@QEAA at AEBV0@@Z(ptr ptr) msvcirt.??0streambuf@@QEAA at AEBV0@@Z -@ stub -arch=win32 ??0strstream@@QAE at ABV0@@Z -@ stub -arch=win64 ??0strstream@@QEAA at AEBV0@@Z -@ stub -arch=win32 ??0strstream@@QAE at PADHH@Z -@ stub -arch=win64 ??0strstream@@QEAA at PEADHH@Z -@ stub -arch=win32 ??0strstream@@QAE at XZ -@ stub -arch=win64 ??0strstream@@QEAA at XZ +@ thiscall -arch=win32 ??0strstream@@QAE at ABV0@@Z(ptr ptr long) msvcirt.??0strstream@@QAE at ABV0@@Z +@ cdecl -arch=win64 ??0strstream@@QEAA at AEBV0@@Z(ptr ptr long) msvcirt.??0strstream@@QEAA at AEBV0@@Z +@ thiscall -arch=win32 ??0strstream@@QAE at PADHH@Z(ptr ptr long long long) msvcirt.??0strstream@@QAE at PADHH@Z +@ cdecl -arch=win64 ??0strstream@@QEAA at PEADHH@Z(ptr ptr long long long) msvcirt.??0strstream@@QEAA at PEADHH@Z +@ thiscall -arch=win32 ??0strstream@@QAE at XZ(ptr long) msvcirt.??0strstream@@QAE at XZ +@ cdecl -arch=win64 ??0strstream@@QEAA at XZ(ptr long) msvcirt.??0strstream@@QEAA at XZ @ thiscall -arch=win32 ??0strstreambuf@@QAE at ABV0@@Z(ptr ptr) msvcirt.??0strstreambuf@@QAE at ABV0@@Z @ cdecl -arch=win64 ??0strstreambuf@@QEAA at AEBV0@@Z(ptr ptr) msvcirt.??0strstreambuf@@QEAA at AEBV0@@Z @ thiscall -arch=win32 ??0strstreambuf@@QAE at H@Z(ptr long) msvcirt.??0strstreambuf@@QAE at H@Z @@ -150,8 +150,8 @@ @ stub -arch=win64 ??1stdiostream@@UEAA at XZ @ thiscall -arch=win32 ??1streambuf@@UAE at XZ(ptr) msvcirt.??1streambuf@@UAE at XZ @ cdecl -arch=win64 ??1streambuf@@UEAA at XZ(ptr) msvcirt.??1streambuf@@UEAA at XZ -@ stub -arch=win32 ??1strstream@@UAE at XZ -@ stub -arch=win64 ??1strstream@@UEAA at XZ +@ thiscall -arch=win32 ??1strstream@@UAE at XZ(ptr) msvcirt.??1strstream@@UAE at XZ +@ cdecl -arch=win64 ??1strstream@@UEAA at XZ(ptr) msvcirt.??1strstream@@UEAA at XZ @ thiscall -arch=win32 ??1strstreambuf@@UAE at XZ(ptr) msvcirt.??1strstreambuf@@UAE at XZ @ cdecl -arch=win64 ??1strstreambuf@@UEAA at XZ(ptr) msvcirt.??1strstreambuf@@UEAA at XZ @ cdecl -arch=win32 ??2 at YAPAXI@Z(long) msvcrt.??2 at YAPAXI@Z @@ -204,8 +204,8 @@ @ stub -arch=win64 ??4stdiostream@@QEAAAEAV0 at AEAV0@@Z @ thiscall -arch=win32 ??4streambuf@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4streambuf@@QAEAAV0 at ABV0@@Z @ cdecl -arch=win64 ??4streambuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4streambuf@@QEAAAEAV0 at AEBV0@@Z -@ stub -arch=win32 ??4strstream@@QAEAAV0 at AAV0@@Z -@ stub -arch=win64 ??4strstream@@QEAAAEAV0 at AEAV0@@Z +@ thiscall -arch=win32 ??4strstream@@QAEAAV0 at AAV0@@Z(ptr ptr) msvcirt.??4strstream@@QAEAAV0 at AAV0@@Z +@ cdecl -arch=win64 ??4strstream@@QEAAAEAV0 at AEAV0@@Z(ptr ptr) msvcirt.??4strstream@@QEAAAEAV0 at AEAV0@@Z @ thiscall -arch=win32 ??4strstreambuf@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4strstreambuf@@QAEAAV0 at ABV0@@Z @ cdecl -arch=win64 ??4strstreambuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4strstreambuf@@QEAAAEAV0 at AEBV0@@Z @ thiscall -arch=win32 ??5istream@@QAEAAV0 at AAC@Z(ptr ptr) msvcirt.??5istream@@QAEAAV0 at AAC@Z @@ -301,7 +301,7 @@ @ extern ??_7stdiobuf@@6B@ msvcirt.??_7stdiobuf@@6B@ # @ extern ??_7stdiostream@@6B@ @ extern ??_7streambuf@@6B@ msvcirt.??_7streambuf@@6B@ -# @ extern ??_7strstream@@6B@ +@ extern ??_7strstream@@6B@ msvcirt.??_7strstream@@6B@ @ extern ??_7strstreambuf@@6B@ msvcirt.??_7strstreambuf@@6B@ # @ extern ??_8fstream@@7Bistream@@@ # @ extern ??_8fstream@@7Bostream@@@ @@ -317,8 +317,8 @@ @ extern ??_8ostrstream@@7B@ msvcirt.??_8ostrstream@@7B@ # @ extern ??_8stdiostream@@7Bistream@@@ # @ extern ??_8stdiostream@@7Bostream@@@ -# @ extern ??_8strstream@@7Bistream@@@ -# @ extern ??_8strstream@@7Bostream@@@ +@ extern ??_8strstream@@7Bistream@@@ msvcirt.??_8strstream@@7Bistream@@@ +@ extern ??_8strstream@@7Bostream@@@ msvcirt.??_8strstream@@7Bostream@@@ @ stub -arch=win32 ??_Dfstream@@QAEXXZ @ stub -arch=win64 ??_Dfstream@@QEAAXXZ @ stub -arch=win32 ??_Difstream@@QAEXXZ @@ -341,8 +341,8 @@ @ cdecl -arch=win64 ??_Dostrstream@@QEAAXXZ(ptr) msvcirt.??_Dostrstream@@QEAAXXZ @ stub -arch=win32 ??_Dstdiostream@@QAEXXZ @ stub -arch=win64 ??_Dstdiostream@@QEAAXXZ -@ stub -arch=win32 ??_Dstrstream@@QAEXXZ -@ stub -arch=win64 ??_Dstrstream@@QEAAXXZ +@ thiscall -arch=win32 ??_Dstrstream@@QAEXXZ(ptr) msvcirt.??_Dstrstream@@QAEXXZ +@ cdecl -arch=win64 ??_Dstrstream@@QEAAXXZ(ptr) msvcirt.??_Dstrstream@@QEAAXXZ @ stub -arch=win32 ??_EIostream_init@@QAEPAXI at Z @ thiscall -arch=win32 ??_Efilebuf@@UAEPAXI at Z(ptr long) msvcirt.??_Efilebuf@@UAEPAXI at Z @ stub -arch=win32 ??_Efstream@@UAEPAXI at Z @@ -359,7 +359,7 @@ @ thiscall -arch=win32 ??_Estdiobuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estdiobuf@@UAEPAXI at Z @ stub -arch=win32 ??_Estdiostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estreambuf@@UAEPAXI at Z -@ stub -arch=win32 ??_Estrstream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Estrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Estrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estrstreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estrstreambuf@@UAEPAXI at Z @ stub -arch=win32 ??_GIostream_init@@QAEPAXI at Z @ thiscall -arch=win32 ??_Gfilebuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gfilebuf@@UAEPAXI at Z @@ -377,7 +377,7 @@ @ thiscall -arch=win32 ??_Gstdiobuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstdiobuf@@UAEPAXI at Z @ stub -arch=win32 ??_Gstdiostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstreambuf@@UAEPAXI at Z -@ stub -arch=win32 ??_Gstrstream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Gstrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gstrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstrstreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstrstreambuf@@UAEPAXI at Z @ cdecl -arch=win32 ?_query_new_handler@@YAP6AHI at ZXZ() msvcrt.?_query_new_handler@@YAP6AHI at ZXZ @ cdecl -arch=win64 ?_query_new_handler@@YAP6AH_K at ZXZ() msvcrt.?_query_new_handler@@YAP6AH_K at ZXZ @@ -579,8 +579,8 @@ @ cdecl -arch=win64 ?pbump at streambuf@@IEAAXH at Z(ptr long) msvcirt.?pbump at streambuf@@IEAAXH at Z @ thiscall -arch=win32 ?pcount at ostrstream@@QBEHXZ(ptr) msvcirt.?pcount at ostrstream@@QBEHXZ @ cdecl -arch=win64 ?pcount at ostrstream@@QEBAHXZ(ptr) msvcirt.?pcount at ostrstream@@QEBAHXZ -@ stub -arch=win32 ?pcount at strstream@@QBEHXZ -@ stub -arch=win64 ?pcount at strstream@@QEBAHXZ +@ thiscall -arch=win32 ?pcount at strstream@@QBEHXZ(ptr) msvcirt.?pcount at strstream@@QBEHXZ +@ cdecl -arch=win64 ?pcount at strstream@@QEBAHXZ(ptr) msvcirt.?pcount at strstream@@QEBAHXZ @ thiscall -arch=win32 ?peek at istream@@QAEHXZ(ptr) msvcirt.?peek at istream@@QAEHXZ @ cdecl -arch=win64 ?peek at istream@@QEAAHXZ(ptr) msvcirt.?peek at istream@@QEAAHXZ @ thiscall -arch=win32 ?pptr at streambuf@@IBEPADXZ(ptr) msvcirt.?pptr at streambuf@@IBEPADXZ @@ -613,8 +613,8 @@ @ cdecl -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ @ stub -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ @ stub -arch=win64 ?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ -@ stub -arch=win32 ?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ -@ stub -arch=win64 ?rdbuf at strstream@@QEBAPEAVstrstreambuf@@XZ +@ thiscall -arch=win32 ?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ +@ cdecl -arch=win64 ?rdbuf at strstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at strstream@@QEBAPEAVstrstreambuf@@XZ @ thiscall -arch=win32 ?rdstate at ios@@QBEHXZ(ptr) msvcirt.?rdstate at ios@@QBEHXZ @ cdecl -arch=win64 ?rdstate at ios@@QEBAHXZ(ptr) msvcirt.?rdstate at ios@@QEBAHXZ @ thiscall -arch=win32 ?read at istream@@QAEAAV1 at PACH@Z(ptr ptr long) msvcirt.?read at istream@@QAEAAV1 at PACH@Z @@ -704,8 +704,8 @@ @ cdecl -arch=win64 ?str at istrstream@@QEAAPEADXZ(ptr) msvcirt.?str at istrstream@@QEAAPEADXZ @ thiscall -arch=win32 ?str at ostrstream@@QAEPADXZ(ptr) msvcirt.?str at ostrstream@@QAEPADXZ @ cdecl -arch=win64 ?str at ostrstream@@QEAAPEADXZ(ptr) msvcirt.?str at ostrstream@@QEAAPEADXZ -@ stub -arch=win32 ?str at strstream@@QAEPADXZ -@ stub -arch=win64 ?str at strstream@@QEAAPEADXZ +@ thiscall -arch=win32 ?str at strstream@@QAEPADXZ(ptr) msvcirt.?str at strstream@@QAEPADXZ +@ cdecl -arch=win64 ?str at strstream@@QEAAPEADXZ(ptr) msvcirt.?str at strstream@@QEAAPEADXZ @ thiscall -arch=win32 ?str at strstreambuf@@QAEPADXZ(ptr) msvcirt.?str at strstreambuf@@QAEPADXZ @ cdecl -arch=win64 ?str at strstreambuf@@QEAAPEADXZ(ptr) msvcirt.?str at strstreambuf@@QEAAPEADXZ @ extern ?sunk_with_stdio at ios@@0HA msvcirt.?sunk_with_stdio at ios@@0HA diff --git a/dlls/msvcrt40/msvcrt40.spec b/dlls/msvcrt40/msvcrt40.spec index 7c83691..40b6eab 100644 --- a/dlls/msvcrt40/msvcrt40.spec +++ b/dlls/msvcrt40/msvcrt40.spec @@ -124,12 +124,12 @@ @ cdecl -arch=win64 ??0streambuf@@IEAA at XZ(ptr) msvcirt.??0streambuf@@IEAA at XZ @ thiscall -arch=win32 ??0streambuf@@QAE at ABV0@@Z(ptr ptr) msvcirt.??0streambuf@@QAE at ABV0@@Z @ cdecl -arch=win64 ??0streambuf@@QEAA at AEBV0@@Z(ptr ptr) msvcirt.??0streambuf@@QEAA at AEBV0@@Z -@ stub -arch=win32 ??0strstream@@QAE at ABV0@@Z -@ stub -arch=win64 ??0strstream@@QEAA at AEBV0@@Z -@ stub -arch=win32 ??0strstream@@QAE at PADHH@Z -@ stub -arch=win64 ??0strstream@@QEAA at PEADHH@Z -@ stub -arch=win32 ??0strstream@@QAE at XZ -@ stub -arch=win64 ??0strstream@@QEAA at XZ +@ thiscall -arch=win32 ??0strstream@@QAE at ABV0@@Z(ptr ptr long) msvcirt.??0strstream@@QAE at ABV0@@Z +@ cdecl -arch=win64 ??0strstream@@QEAA at AEBV0@@Z(ptr ptr long) msvcirt.??0strstream@@QEAA at AEBV0@@Z +@ thiscall -arch=win32 ??0strstream@@QAE at PADHH@Z(ptr ptr long long long) msvcirt.??0strstream@@QAE at PADHH@Z +@ cdecl -arch=win64 ??0strstream@@QEAA at PEADHH@Z(ptr ptr long long long) msvcirt.??0strstream@@QEAA at PEADHH@Z +@ thiscall -arch=win32 ??0strstream@@QAE at XZ(ptr long) msvcirt.??0strstream@@QAE at XZ +@ cdecl -arch=win64 ??0strstream@@QEAA at XZ(ptr long) msvcirt.??0strstream@@QEAA at XZ @ thiscall -arch=win32 ??0strstreambuf@@QAE at ABV0@@Z(ptr ptr) msvcirt.??0strstreambuf@@QAE at ABV0@@Z @ cdecl -arch=win64 ??0strstreambuf@@QEAA at AEBV0@@Z(ptr ptr) msvcirt.??0strstreambuf@@QEAA at AEBV0@@Z @ thiscall -arch=win32 ??0strstreambuf@@QAE at H@Z(ptr long) msvcirt.??0strstreambuf@@QAE at H@Z @@ -182,8 +182,8 @@ @ stub -arch=win64 ??1stdiostream@@UEAA at XZ @ thiscall -arch=win32 ??1streambuf@@UAE at XZ(ptr) msvcirt.??1streambuf@@UAE at XZ @ cdecl -arch=win64 ??1streambuf@@UEAA at XZ(ptr) msvcirt.??1streambuf@@UEAA at XZ -@ stub -arch=win32 ??1strstream@@UAE at XZ -@ stub -arch=win64 ??1strstream@@UEAA at XZ +@ thiscall -arch=win32 ??1strstream@@UAE at XZ(ptr) msvcirt.??1strstream@@UAE at XZ +@ cdecl -arch=win64 ??1strstream@@UEAA at XZ(ptr) msvcirt.??1strstream@@UEAA at XZ @ thiscall -arch=win32 ??1strstreambuf@@UAE at XZ(ptr) msvcirt.??1strstreambuf@@UAE at XZ @ cdecl -arch=win64 ??1strstreambuf@@UEAA at XZ(ptr) msvcirt.??1strstreambuf@@UEAA at XZ @ thiscall -arch=i386 ??1type_info@@UAE at XZ(ptr) msvcrt.??1type_info@@UAE at XZ @@ -248,8 +248,8 @@ @ stub -arch=win64 ??4stdiostream@@QEAAAEAV0 at AEAV0@@Z @ thiscall -arch=win32 ??4streambuf@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4streambuf@@QAEAAV0 at ABV0@@Z @ cdecl -arch=win64 ??4streambuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4streambuf@@QEAAAEAV0 at AEBV0@@Z -@ stub -arch=win32 ??4strstream@@QAEAAV0 at AAV0@@Z -@ stub -arch=win64 ??4strstream@@QEAAAEAV0 at AEAV0@@Z +@ thiscall -arch=win32 ??4strstream@@QAEAAV0 at AAV0@@Z(ptr ptr) msvcirt.??4strstream@@QAEAAV0 at AAV0@@Z +@ cdecl -arch=win64 ??4strstream@@QEAAAEAV0 at AEAV0@@Z(ptr ptr) msvcirt.??4strstream@@QEAAAEAV0 at AEAV0@@Z @ thiscall -arch=win32 ??4strstreambuf@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4strstreambuf@@QAEAAV0 at ABV0@@Z @ cdecl -arch=win64 ??4strstreambuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4strstreambuf@@QEAAAEAV0 at AEBV0@@Z @ thiscall -arch=win32 ??5istream@@QAEAAV0 at AAC@Z(ptr ptr) msvcirt.??5istream@@QAEAAV0 at AAC@Z @@ -354,7 +354,7 @@ @ extern ??_7stdiobuf@@6B@ msvcirt.??_7stdiobuf@@6B@ # @ extern ??_7stdiostream@@6B@ @ extern ??_7streambuf@@6B@ msvcirt.??_7streambuf@@6B@ -# @ extern ??_7strstream@@6B@ +@ extern ??_7strstream@@6B@ msvcirt.??_7strstream@@6B@ @ extern ??_7strstreambuf@@6B@ msvcirt.??_7strstreambuf@@6B@ # @ extern ??_8fstream@@7Bistream@@@ # @ extern ??_8fstream@@7Bostream@@@ @@ -370,8 +370,8 @@ @ extern ??_8ostrstream@@7B@ msvcirt.??_8ostrstream@@7B@ # @ extern ??_8stdiostream@@7Bistream@@@ # @ extern ??_8stdiostream@@7Bostream@@@ -# @ extern ??_8strstream@@7Bistream@@@ -# @ extern ??_8strstream@@7Bostream@@@ +@ extern ??_8strstream@@7Bistream@@@ msvcirt.??_8strstream@@7Bistream@@@ +@ extern ??_8strstream@@7Bostream@@@ msvcirt.??_8strstream@@7Bostream@@@ @ stub -arch=win32 ??_Dfstream@@QAEXXZ @ stub -arch=win64 ??_Dfstream@@QEAAXXZ @ stub -arch=win32 ??_Difstream@@QAEXXZ @@ -394,8 +394,8 @@ @ cdecl -arch=win64 ??_Dostrstream@@QEAAXXZ(ptr) msvcirt.??_Dostrstream@@QEAAXXZ @ stub -arch=win32 ??_Dstdiostream@@QAEXXZ @ stub -arch=win64 ??_Dstdiostream@@QEAAXXZ -@ stub -arch=win32 ??_Dstrstream@@QAEXXZ -@ stub -arch=win64 ??_Dstrstream@@QEAAXXZ +@ thiscall -arch=win32 ??_Dstrstream@@QAEXXZ(ptr) msvcirt.??_Dstrstream@@QAEXXZ +@ cdecl -arch=win64 ??_Dstrstream@@QEAAXXZ(ptr) msvcirt.??_Dstrstream@@QEAAXXZ @ stub -arch=win32 ??_EIostream_init@@QAEPAXI at Z @ thiscall -arch=win32 ??_E__non_rtti_object@@UAEPAXI at Z(ptr long) msvcrt.??_E__non_rtti_object@@UAEPAXI at Z @ thiscall -arch=win32 ??_Ebad_cast@@UAEPAXI at Z(ptr long) msvcrt.??_Ebad_cast@@UAEPAXI at Z @@ -417,7 +417,7 @@ @ thiscall -arch=win32 ??_Estdiobuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estdiobuf@@UAEPAXI at Z @ stub -arch=win32 ??_Estdiostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estreambuf@@UAEPAXI at Z -@ stub -arch=win32 ??_Estrstream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Estrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Estrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estrstreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estrstreambuf@@UAEPAXI at Z @ stub -arch=win32 ??_GIostream_init@@QAEPAXI at Z @ thiscall -arch=win32 ??_G__non_rtti_object@@UAEPAXI at Z(ptr long) msvcrt.??_G__non_rtti_object@@UAEPAXI at Z @@ -440,7 +440,7 @@ @ thiscall -arch=win32 ??_Gstdiobuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstdiobuf@@UAEPAXI at Z @ stub -arch=win32 ??_Gstdiostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstreambuf@@UAEPAXI at Z -@ stub -arch=win32 ??_Gstrstream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Gstrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gstrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstrstreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstrstreambuf@@UAEPAXI at Z @ cdecl -arch=win32 ?_query_new_handler@@YAP6AHI at ZXZ() msvcrt.?_query_new_handler@@YAP6AHI at ZXZ @ cdecl -arch=win64 ?_query_new_handler@@YAP6AH_K at ZXZ() msvcrt.?_query_new_handler@@YAP6AH_K at ZXZ @@ -648,8 +648,8 @@ @ cdecl -arch=win64 ?pbump at streambuf@@IEAAXH at Z(ptr long) msvcirt.?pbump at streambuf@@IEAAXH at Z @ thiscall -arch=win32 ?pcount at ostrstream@@QBEHXZ(ptr) msvcirt.?pcount at ostrstream@@QBEHXZ @ cdecl -arch=win64 ?pcount at ostrstream@@QEBAHXZ(ptr) msvcirt.?pcount at ostrstream@@QEBAHXZ -@ stub -arch=win32 ?pcount at strstream@@QBEHXZ -@ stub -arch=win64 ?pcount at strstream@@QEBAHXZ +@ thiscall -arch=win32 ?pcount at strstream@@QBEHXZ(ptr) msvcirt.?pcount at strstream@@QBEHXZ +@ cdecl -arch=win64 ?pcount at strstream@@QEBAHXZ(ptr) msvcirt.?pcount at strstream@@QEBAHXZ @ thiscall -arch=win32 ?peek at istream@@QAEHXZ(ptr) msvcirt.?peek at istream@@QAEHXZ @ cdecl -arch=win64 ?peek at istream@@QEAAHXZ(ptr) msvcirt.?peek at istream@@QEAAHXZ @ thiscall -arch=win32 ?pptr at streambuf@@IBEPADXZ(ptr) msvcirt.?pptr at streambuf@@IBEPADXZ @@ -684,8 +684,8 @@ @ cdecl -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ @ stub -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ @ stub -arch=win64 ?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ -@ stub -arch=win32 ?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ -@ stub -arch=win64 ?rdbuf at strstream@@QEBAPEAVstrstreambuf@@XZ +@ thiscall -arch=win32 ?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ +@ cdecl -arch=win64 ?rdbuf at strstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at strstream@@QEBAPEAVstrstreambuf@@XZ @ thiscall -arch=win32 ?rdstate at ios@@QBEHXZ(ptr) msvcirt.?rdstate at ios@@QBEHXZ @ cdecl -arch=win64 ?rdstate at ios@@QEBAHXZ(ptr) msvcirt.?rdstate at ios@@QEBAHXZ @ thiscall -arch=win32 ?read at istream@@QAEAAV1 at PACH@Z(ptr ptr long) msvcirt.?read at istream@@QAEAAV1 at PACH@Z @@ -776,8 +776,8 @@ @ cdecl -arch=win64 ?str at istrstream@@QEAAPEADXZ(ptr) msvcirt.?str at istrstream@@QEAAPEADXZ @ thiscall -arch=win32 ?str at ostrstream@@QAEPADXZ(ptr) msvcirt.?str at ostrstream@@QAEPADXZ @ cdecl -arch=win64 ?str at ostrstream@@QEAAPEADXZ(ptr) msvcirt.?str at ostrstream@@QEAAPEADXZ -@ stub -arch=win32 ?str at strstream@@QAEPADXZ -@ stub -arch=win64 ?str at strstream@@QEAAPEADXZ +@ thiscall -arch=win32 ?str at strstream@@QAEPADXZ(ptr) msvcirt.?str at strstream@@QAEPADXZ +@ cdecl -arch=win64 ?str at strstream@@QEAAPEADXZ(ptr) msvcirt.?str at strstream@@QEAAPEADXZ @ thiscall -arch=win32 ?str at strstreambuf@@QAEPADXZ(ptr) msvcirt.?str at strstreambuf@@QAEPADXZ @ cdecl -arch=win64 ?str at strstreambuf@@QEAAPEADXZ(ptr) msvcirt.?str at strstreambuf@@QEAAPEADXZ @ extern ?sunk_with_stdio at ios@@0HA msvcirt.?sunk_with_stdio at ios@@0HA -- 2.7.4 From matellanesivan at gmail.com Fri Oct 21 12:34:02 2016 From: matellanesivan at gmail.com (=?UTF-8?q?Iv=C3=A1n=20Matellanes?=) Date: Fri, 21 Oct 2016 19:34:02 +0200 Subject: [2/4] msvcirt: Implement strstream constructors. In-Reply-To: <1477071244-13290-1-git-send-email-matellanesivan@gmail.com> References: <1477071244-13290-1-git-send-email-matellanesivan@gmail.com> Message-ID: <1477071244-13290-2-git-send-email-matellanesivan@gmail.com> Signed-off-by: Iván Matellanes --- dlls/msvcirt/msvcirt.c | 59 ++++++- dlls/msvcirt/tests/msvcirt.c | 356 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 409 insertions(+), 6 deletions(-) diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index 99388fe..9c36e69 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -4225,13 +4225,44 @@ iostream* __thiscall iostream_scalar_dtor(ios *base, unsigned int flags) return this; } +static iostream* iostream_internal_copy_ctor(iostream *this, const iostream *copy, const vtable_ptr *vtbl, BOOL virt_init) +{ + ios *base, *base_copy = istream_get_ios(©->base1); + + if (virt_init) { + this->base1.vbtable = iostream_vbtable_istream; + this->base2.vbtable = iostream_vbtable_ostream; + base = istream_get_ios(&this->base1); + ios_copy_ctor(base, base_copy); + } else + base = istream_get_ios(&this->base1); + ios_init(base, base_copy->sb); + istream_ctor(&this->base1, FALSE); + ostream_ctor(&this->base2, FALSE); + base->vtable = vtbl; + return this; +} + +static iostream* iostream_internal_sb_ctor(iostream *this, streambuf *sb, const vtable_ptr *vtbl, BOOL virt_init) +{ + ios *base; + + iostream_ctor(this, virt_init); + base = istream_get_ios(&this->base1); + if (sb) + ios_init(base, sb); + base->vtable = vtbl; + base->delbuf = 1; + return this; +} + /* ??0strstream@@QAE at ABV0@@Z */ /* ??0strstream@@QEAA at AEBV0@@Z */ DEFINE_THISCALL_WRAPPER(strstream_copy_ctor, 12) iostream* __thiscall strstream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init) { - FIXME("(%p %p %d) stub\n", this, copy, virt_init); - return this; + TRACE("(%p %p %d)\n", this, copy, virt_init); + return iostream_internal_copy_ctor(this, copy, &MSVCP_strstream_vtable, virt_init); } /* ??0strstream@@QAE at PADHH@Z */ @@ -4239,8 +4270,17 @@ iostream* __thiscall strstream_copy_ctor(iostream *this, const iostream *copy, B DEFINE_THISCALL_WRAPPER(strstream_buffer_ctor, 20) iostream* __thiscall strstream_buffer_ctor(iostream *this, char *buffer, int length, int mode, BOOL virt_init) { - FIXME("(%p %p %d %d %d) stub\n", this, buffer, length, mode, virt_init); - return this; + strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf)); + + TRACE("(%p %p %d %d %d)\n", this, buffer, length, mode, virt_init); + + if (ssb) { + strstreambuf_buffer_ctor(ssb, buffer, length, buffer); + if ((mode & OPENMODE_out) && (mode & (OPENMODE_app|OPENMODE_ate))) + ssb->base.pptr = buffer + strlen(buffer); + return iostream_internal_sb_ctor(this, &ssb->base, &MSVCP_strstream_vtable, virt_init); + } + return iostream_internal_sb_ctor(this, NULL, &MSVCP_strstream_vtable, virt_init); } /* ??0strstream@@QAE at XZ */ @@ -4248,8 +4288,15 @@ iostream* __thiscall strstream_buffer_ctor(iostream *this, char *buffer, int len DEFINE_THISCALL_WRAPPER(strstream_ctor, 8) iostream* __thiscall strstream_ctor(iostream *this, BOOL virt_init) { - FIXME("(%p %d) stub\n", this, virt_init); - return this; + strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf)); + + TRACE("(%p %d)\n", this, virt_init); + + if (ssb) { + strstreambuf_ctor(ssb); + return iostream_internal_sb_ctor(this, &ssb->base, &MSVCP_strstream_vtable, virt_init); + } + return iostream_internal_sb_ctor(this, NULL, &MSVCP_strstream_vtable, virt_init); } /* ?pcount at strstream@@QBEHXZ */ diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c index ed87a23..de5af0d 100644 --- a/dlls/msvcirt/tests/msvcirt.c +++ b/dlls/msvcirt/tests/msvcirt.c @@ -404,6 +404,14 @@ static void (*__thiscall p_iostream_vbase_dtor)(iostream*); static iostream* (*__thiscall p_iostream_assign_sb)(iostream*, streambuf*); static iostream* (*__thiscall p_iostream_assign)(iostream*, const iostream*); +/* strstream */ +static iostream* (*__thiscall p_strstream_copy_ctor)(iostream*, const iostream*, BOOL); +static iostream* (*__thiscall p_strstream_buffer_ctor)(iostream*, char*, int, int, BOOL); +static iostream* (*__thiscall p_strstream_ctor)(iostream*, BOOL); +static void (*__thiscall p_strstream_dtor)(ios*); +static void (*__thiscall p_strstream_vbase_dtor)(iostream*); +static iostream* (*__thiscall p_strstream_assign)(iostream*, const iostream*); + /* Iostream_init */ static void* (*__thiscall p_Iostream_init_ios_ctor)(void*, ios*, int); @@ -681,6 +689,13 @@ static BOOL init(void) SET(p_iostream_assign_sb, "??4iostream@@IEAAAEAV0 at PEAVstreambuf@@@Z"); SET(p_iostream_assign, "??4iostream@@IEAAAEAV0 at AEAV0@@Z"); + SET(p_strstream_copy_ctor, "??0strstream@@QEAA at AEBV0@@Z"); + SET(p_strstream_buffer_ctor, "??0strstream@@QEAA at PEADHH@Z"); + SET(p_strstream_ctor, "??0strstream@@QEAA at XZ"); + SET(p_strstream_dtor, "??1strstream@@UEAA at XZ"); + SET(p_strstream_vbase_dtor, "??_Dstrstream@@QEAAXXZ"); + SET(p_strstream_assign, "??4strstream@@QEAAAEAV0 at AEAV0@@Z"); + SET(p_Iostream_init_ios_ctor, "??0Iostream_init@@QEAA at AEAVios@@H at Z"); } else { p_operator_new = (void*)GetProcAddress(msvcrt, "??2 at YAPAXI@Z"); @@ -875,6 +890,13 @@ static BOOL init(void) SET(p_iostream_assign_sb, "??4iostream@@IAEAAV0 at PAVstreambuf@@@Z"); SET(p_iostream_assign, "??4iostream@@IAEAAV0 at AAV0@@Z"); + SET(p_strstream_copy_ctor, "??0strstream@@QAE at ABV0@@Z"); + SET(p_strstream_buffer_ctor, "??0strstream@@QAE at PADHH@Z"); + SET(p_strstream_ctor, "??0strstream@@QAE at XZ"); + SET(p_strstream_dtor, "??1strstream@@UAE at XZ"); + SET(p_strstream_vbase_dtor, "??_Dstrstream@@QAEXXZ"); + SET(p_strstream_assign, "??4strstream@@QAEAAV0 at AAV0@@Z"); + SET(p_Iostream_init_ios_ctor, "??0Iostream_init@@QAE at AAVios@@H at Z"); } SET(p_ios_static_lock, "?x_lockc at ios@@0U_CRT_CRITICAL_SECTION@@A"); @@ -6658,6 +6680,339 @@ static void test_iostream(void) ok(ios2.base_ios.do_lock == 0xcdcdcdcd, "expected %d got %d\n", 0xcdcdcdcd, ios2.base_ios.do_lock); } +static void test_strstream(void) +{ + iostream ios1, ios2, *pios; + ostream *pos; + strstreambuf *pssb; + char buffer[32]; + + memset(&ios1, 0xab, sizeof(iostream)); + memset(&ios2, 0xab, sizeof(iostream)); + + /* constructors/destructors */ + pios = call_func2(p_strstream_ctor, &ios1, TRUE); + pssb = (strstreambuf*) ios1.base_ios.sb; + ok(pios == &ios1, "wrong return, expected %p got %p\n", &ios1, pios); + ok(ios1.base1.extract_delim == 0, "expected 0 got %d\n", ios1.base1.extract_delim); + ok(ios1.base1.count == 0, "expected 0 got %d\n", ios1.base1.count); + ok(ios1.base2.unknown == 0, "expected 0 got %d\n", ios1.base2.unknown); + ok(ios1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ios1.base_ios.state); + ok(ios1.base_ios.delbuf == 1, "expected 1 got %d\n", ios1.base_ios.delbuf); + ok(ios1.base_ios.tie == NULL, "expected %p got %p\n", NULL, ios1.base_ios.tie); + ok(ios1.base_ios.flags == FLAGS_skipws, "expected %x got %x\n", FLAGS_skipws, ios1.base_ios.flags); + ok(ios1.base_ios.precision == 6, "expected 6 got %d\n", ios1.base_ios.precision); + ok(ios1.base_ios.fill == ' ', "expected 32 got %d\n", ios1.base_ios.fill); + ok(ios1.base_ios.width == 0, "expected 0 got %d\n", ios1.base_ios.width); + ok(ios1.base_ios.do_lock == -1, "expected -1 got %d\n", ios1.base_ios.do_lock); + ok(pssb->dynamic == 1, "expected 1, got %d\n", pssb->dynamic); + ok(pssb->increase == 1, "expected 1, got %d\n", pssb->increase); + ok(pssb->constant == 0, "expected 0, got %d\n", pssb->constant); + ok(pssb->f_alloc == NULL, "expected %p, got %p\n", NULL, pssb->f_alloc); + ok(pssb->f_free == NULL, "expected %p, got %p\n", NULL, pssb->f_free); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == NULL, "wrong buffer, expected %p got %p\n", NULL, pssb->base.base); + ok(pssb->base.ebuf == NULL, "wrong buffer end, expected %p got %p\n", NULL, pssb->base.ebuf); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_strstream_vbase_dtor, &ios1); + ok(ios1.base_ios.sb == NULL, "expected %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, ios1.base_ios.state); + ios1.base1.extract_delim = ios1.base1.count = 0xabababab; + ios1.base2.unknown = 0xabababab; + memset(&ios1.base_ios, 0xab, sizeof(ios)); + ios1.base_ios.delbuf = 0; + pios = call_func2(p_strstream_ctor, &ios1, FALSE); + pssb = (strstreambuf*) ios1.base_ios.sb; + ok(pios == &ios1, "wrong return, expected %p got %p\n", &ios1, pios); + ok(ios1.base1.extract_delim == 0, "expected 0 got %d\n", ios1.base1.extract_delim); + ok(ios1.base1.count == 0, "expected 0 got %d\n", ios1.base1.count); + ok(ios1.base2.unknown == 0, "expected 0 got %d\n", ios1.base2.unknown); + ok(ios1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.state); + ok(ios1.base_ios.delbuf == 1, "expected 1 got %d\n", ios1.base_ios.delbuf); + ok(ios1.base_ios.tie == ios2.base_ios.tie, "expected %p got %p\n", ios2.base_ios.tie, ios1.base_ios.tie); + ok(ios1.base_ios.flags == 0xabababab, "expected %x got %x\n", 0xabababab, ios1.base_ios.flags); + ok(ios1.base_ios.precision == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.precision); + ok(ios1.base_ios.fill == (char) 0xab, "expected -85 got %d\n", ios1.base_ios.fill); + ok(ios1.base_ios.width == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.width); + ok(ios1.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.do_lock); + ok(pssb->dynamic == 1, "expected 1, got %d\n", pssb->dynamic); + ok(pssb->increase == 1, "expected 1, got %d\n", pssb->increase); + ok(pssb->constant == 0, "expected 0, got %d\n", pssb->constant); + ok(pssb->f_alloc == NULL, "expected %p, got %p\n", NULL, pssb->f_alloc); + ok(pssb->f_free == NULL, "expected %p, got %p\n", NULL, pssb->f_free); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == NULL, "wrong buffer, expected %p got %p\n", NULL, pssb->base.base); + ok(pssb->base.ebuf == NULL, "wrong buffer end, expected %p got %p\n", NULL, pssb->base.ebuf); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_strstream_dtor, &ios1.base_ios); + ok(ios1.base_ios.sb == &pssb->base, "expected %p got %p\n", &pssb->base, ios1.base_ios.sb); + ok(ios1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.state); + call_func1(p_strstreambuf_dtor, pssb); + p_operator_delete(pssb); + + memset(&ios1, 0xab, sizeof(iostream)); + pios = call_func5(p_strstream_buffer_ctor, &ios1, buffer, 32, 0, TRUE); + pssb = (strstreambuf*) ios1.base_ios.sb; + ok(pios == &ios1, "wrong return, expected %p got %p\n", &ios1, pios); + ok(ios1.base1.extract_delim == 0, "expected 0 got %d\n", ios1.base1.extract_delim); + ok(ios1.base1.count == 0, "expected 0 got %d\n", ios1.base1.count); + ok(ios1.base2.unknown == 0, "expected 0 got %d\n", ios1.base2.unknown); + ok(ios1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ios1.base_ios.state); + ok(ios1.base_ios.delbuf == 1, "expected 1 got %d\n", ios1.base_ios.delbuf); + ok(ios1.base_ios.tie == NULL, "expected %p got %p\n", NULL, ios1.base_ios.tie); + ok(ios1.base_ios.flags == FLAGS_skipws, "expected %x got %x\n", FLAGS_skipws, ios1.base_ios.flags); + ok(ios1.base_ios.precision == 6, "expected 6 got %d\n", ios1.base_ios.precision); + ok(ios1.base_ios.fill == ' ', "expected 32 got %d\n", ios1.base_ios.fill); + ok(ios1.base_ios.width == 0, "expected 0 got %d\n", ios1.base_ios.width); + ok(ios1.base_ios.do_lock == -1, "expected -1 got %d\n", ios1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); + ok(pssb->base.ebuf == buffer + 32, "wrong buffer end, expected %p got %p\n", buffer + 32, pssb->base.ebuf); + ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); + ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); + ok(pssb->base.egptr == buffer, "wrong get end, expected %p got %p\n", buffer, pssb->base.egptr); + ok(pssb->base.pbase == buffer, "wrong put base, expected %p got %p\n", buffer, pssb->base.pbase); + ok(pssb->base.pptr == buffer, "wrong put pointer, expected %p got %p\n", buffer, pssb->base.pptr); + ok(pssb->base.epptr == buffer + 32, "wrong put end, expected %p got %p\n", buffer + 32, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_strstream_vbase_dtor, &ios1); + ok(ios1.base_ios.sb == NULL, "expected %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, ios1.base_ios.state); + memset(&ios1, 0xab, sizeof(iostream)); + pios = call_func5(p_strstream_buffer_ctor, &ios1, buffer, 16, OPENMODE_in, TRUE); + pssb = (strstreambuf*) ios1.base_ios.sb; + ok(pios == &ios1, "wrong return, expected %p got %p\n", &ios1, pios); + ok(ios1.base1.extract_delim == 0, "expected 0 got %d\n", ios1.base1.extract_delim); + ok(ios1.base1.count == 0, "expected 0 got %d\n", ios1.base1.count); + ok(ios1.base2.unknown == 0, "expected 0 got %d\n", ios1.base2.unknown); + ok(ios1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ios1.base_ios.state); + ok(ios1.base_ios.delbuf == 1, "expected 1 got %d\n", ios1.base_ios.delbuf); + ok(ios1.base_ios.tie == NULL, "expected %p got %p\n", NULL, ios1.base_ios.tie); + ok(ios1.base_ios.flags == FLAGS_skipws, "expected %x got %x\n", FLAGS_skipws, ios1.base_ios.flags); + ok(ios1.base_ios.precision == 6, "expected 6 got %d\n", ios1.base_ios.precision); + ok(ios1.base_ios.fill == ' ', "expected 32 got %d\n", ios1.base_ios.fill); + ok(ios1.base_ios.width == 0, "expected 0 got %d\n", ios1.base_ios.width); + ok(ios1.base_ios.do_lock == -1, "expected -1 got %d\n", ios1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); + ok(pssb->base.ebuf == buffer + 16, "wrong buffer end, expected %p got %p\n", buffer + 16, pssb->base.ebuf); + ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); + ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); + ok(pssb->base.egptr == buffer, "wrong get end, expected %p got %p\n", buffer, pssb->base.egptr); + ok(pssb->base.pbase == buffer, "wrong put base, expected %p got %p\n", buffer, pssb->base.pbase); + ok(pssb->base.pptr == buffer, "wrong put pointer, expected %p got %p\n", buffer, pssb->base.pptr); + ok(pssb->base.epptr == buffer + 16, "wrong put end, expected %p got %p\n", buffer + 16, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_strstream_vbase_dtor, &ios1); + ok(ios1.base_ios.sb == NULL, "expected %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, ios1.base_ios.state); + memset(&ios1, 0xab, sizeof(iostream)); + pios = call_func5(p_strstream_buffer_ctor, &ios1, buffer, -1, OPENMODE_in|OPENMODE_out, TRUE); + pssb = (strstreambuf*) ios1.base_ios.sb; + ok(pios == &ios1, "wrong return, expected %p got %p\n", &ios1, pios); + ok(ios1.base1.extract_delim == 0, "expected 0 got %d\n", ios1.base1.extract_delim); + ok(ios1.base1.count == 0, "expected 0 got %d\n", ios1.base1.count); + ok(ios1.base2.unknown == 0, "expected 0 got %d\n", ios1.base2.unknown); + ok(ios1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ios1.base_ios.state); + ok(ios1.base_ios.delbuf == 1, "expected 1 got %d\n", ios1.base_ios.delbuf); + ok(ios1.base_ios.tie == NULL, "expected %p got %p\n", NULL, ios1.base_ios.tie); + ok(ios1.base_ios.flags == FLAGS_skipws, "expected %x got %x\n", FLAGS_skipws, ios1.base_ios.flags); + ok(ios1.base_ios.precision == 6, "expected 6 got %d\n", ios1.base_ios.precision); + ok(ios1.base_ios.fill == ' ', "expected 32 got %d\n", ios1.base_ios.fill); + ok(ios1.base_ios.width == 0, "expected 0 got %d\n", ios1.base_ios.width); + ok(ios1.base_ios.do_lock == -1, "expected -1 got %d\n", ios1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); + ok(pssb->base.ebuf == buffer + 0x7fffffff || pssb->base.ebuf == (char*) -1, + "wrong buffer end, expected %p + 0x7fffffff or -1, got %p\n", buffer, pssb->base.ebuf); + ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); + ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); + ok(pssb->base.egptr == buffer, "wrong get end, expected %p got %p\n", buffer, pssb->base.egptr); + ok(pssb->base.pbase == buffer, "wrong put base, expected %p got %p\n", buffer, pssb->base.pbase); + ok(pssb->base.pptr == buffer, "wrong put pointer, expected %p got %p\n", buffer, pssb->base.pptr); + ok(pssb->base.epptr == buffer + 0x7fffffff || pssb->base.epptr == (char*) -1, + "wrong buffer end, expected %p + 0x7fffffff or -1, got %p\n", buffer, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_strstream_vbase_dtor, &ios1); + ok(ios1.base_ios.sb == NULL, "expected %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, ios1.base_ios.state); + ios1.base1.extract_delim = ios1.base1.count = 0xabababab; + ios1.base2.unknown = 0xabababab; + memset(&ios1.base_ios, 0xab, sizeof(ios)); + ios1.base_ios.delbuf = 0; + strcpy(buffer, "Test"); + pios = call_func5(p_strstream_buffer_ctor, &ios1, buffer, 0, OPENMODE_in|OPENMODE_app, FALSE); + pssb = (strstreambuf*) ios1.base_ios.sb; + ok(pios == &ios1, "wrong return, expected %p got %p\n", &ios1, pios); + ok(ios1.base1.extract_delim == 0, "expected 0 got %d\n", ios1.base1.extract_delim); + ok(ios1.base1.count == 0, "expected 0 got %d\n", ios1.base1.count); + ok(ios1.base2.unknown == 0, "expected 0 got %d\n", ios1.base2.unknown); + ok(ios1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.state); + ok(ios1.base_ios.delbuf == 1, "expected 1 got %d\n", ios1.base_ios.delbuf); + ok(ios1.base_ios.tie == ios2.base_ios.tie, "expected %p got %p\n", ios2.base_ios.tie, ios1.base_ios.tie); + ok(ios1.base_ios.flags == 0xabababab, "expected %x got %x\n", 0xabababab, ios1.base_ios.flags); + ok(ios1.base_ios.precision == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.precision); + ok(ios1.base_ios.fill == (char) 0xab, "expected -85 got %d\n", ios1.base_ios.fill); + ok(ios1.base_ios.width == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.width); + ok(ios1.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); + ok(pssb->base.ebuf == buffer + 4, "wrong buffer end, expected %p got %p\n", buffer + 4, pssb->base.ebuf); + ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); + ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); + ok(pssb->base.egptr == buffer, "wrong get end, expected %p got %p\n", buffer, pssb->base.egptr); + ok(pssb->base.pbase == buffer, "wrong put base, expected %p got %p\n", buffer, pssb->base.pbase); + ok(pssb->base.pptr == buffer, "wrong put pointer, expected %p got %p\n", buffer, pssb->base.pptr); + ok(pssb->base.epptr == buffer + 4, "wrong put end, expected %p got %p\n", buffer + 4, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_strstream_dtor, &ios1.base_ios); + ok(ios1.base_ios.sb == &pssb->base, "expected %p got %p\n", &pssb->base, ios1.base_ios.sb); + ok(ios1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.state); + call_func1(p_strstreambuf_dtor, pssb); + p_operator_delete(pssb); + memset(&ios1, 0xab, sizeof(iostream)); + pios = call_func5(p_strstream_buffer_ctor, &ios1, buffer, 16, OPENMODE_ate, TRUE); + pssb = (strstreambuf*) ios1.base_ios.sb; + ok(pios == &ios1, "wrong return, expected %p got %p\n", &ios1, pios); + ok(ios1.base1.extract_delim == 0, "expected 0 got %d\n", ios1.base1.extract_delim); + ok(ios1.base1.count == 0, "expected 0 got %d\n", ios1.base1.count); + ok(ios1.base2.unknown == 0, "expected 0 got %d\n", ios1.base2.unknown); + ok(ios1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ios1.base_ios.state); + ok(ios1.base_ios.delbuf == 1, "expected 1 got %d\n", ios1.base_ios.delbuf); + ok(ios1.base_ios.tie == NULL, "expected %p got %p\n", NULL, ios1.base_ios.tie); + ok(ios1.base_ios.flags == FLAGS_skipws, "expected %x got %x\n", FLAGS_skipws, ios1.base_ios.flags); + ok(ios1.base_ios.precision == 6, "expected 6 got %d\n", ios1.base_ios.precision); + ok(ios1.base_ios.fill == ' ', "expected 32 got %d\n", ios1.base_ios.fill); + ok(ios1.base_ios.width == 0, "expected 0 got %d\n", ios1.base_ios.width); + ok(ios1.base_ios.do_lock == -1, "expected -1 got %d\n", ios1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); + ok(pssb->base.ebuf == buffer + 16, "wrong buffer end, expected %p got %p\n", buffer + 16, pssb->base.ebuf); + ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); + ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); + ok(pssb->base.egptr == buffer, "wrong get end, expected %p got %p\n", buffer, pssb->base.egptr); + ok(pssb->base.pbase == buffer, "wrong put base, expected %p got %p\n", buffer, pssb->base.pbase); + ok(pssb->base.pptr == buffer, "wrong put pointer, expected %p got %p\n", buffer, pssb->base.pptr); + ok(pssb->base.epptr == buffer + 16, "wrong put end, expected %p got %p\n", buffer + 16, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_strstream_vbase_dtor, &ios1); + ok(ios1.base_ios.sb == NULL, "expected %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, ios1.base_ios.state); + pios = call_func5(p_strstream_buffer_ctor, &ios1, buffer, 16, OPENMODE_out|OPENMODE_ate, TRUE); + pssb = (strstreambuf*) ios1.base_ios.sb; + ok(pios == &ios1, "wrong return, expected %p got %p\n", &ios1, pios); + ok(ios1.base1.extract_delim == 0, "expected 0 got %d\n", ios1.base1.extract_delim); + ok(ios1.base1.count == 0, "expected 0 got %d\n", ios1.base1.count); + ok(ios1.base2.unknown == 0, "expected 0 got %d\n", ios1.base2.unknown); + ok(ios1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ios1.base_ios.state); + ok(ios1.base_ios.delbuf == 1, "expected 1 got %d\n", ios1.base_ios.delbuf); + ok(ios1.base_ios.tie == NULL, "expected %p got %p\n", NULL, ios1.base_ios.tie); + ok(ios1.base_ios.flags == FLAGS_skipws, "expected %x got %x\n", FLAGS_skipws, ios1.base_ios.flags); + ok(ios1.base_ios.precision == 6, "expected 6 got %d\n", ios1.base_ios.precision); + ok(ios1.base_ios.fill == ' ', "expected 32 got %d\n", ios1.base_ios.fill); + ok(ios1.base_ios.width == 0, "expected 0 got %d\n", ios1.base_ios.width); + ok(ios1.base_ios.do_lock == -1, "expected -1 got %d\n", ios1.base_ios.do_lock); + ok(pssb->dynamic == 0, "expected 0, got %d\n", pssb->dynamic); + ok(pssb->constant == 1, "expected 1, got %d\n", pssb->constant); + ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); + ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); + ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); + ok(pssb->base.ebuf == buffer + 16, "wrong buffer end, expected %p got %p\n", buffer + 16, pssb->base.ebuf); + ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); + ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); + ok(pssb->base.egptr == buffer, "wrong get end, expected %p got %p\n", buffer, pssb->base.egptr); + ok(pssb->base.pbase == buffer, "wrong put base, expected %p got %p\n", buffer, pssb->base.pbase); + ok(pssb->base.pptr == buffer + 4, "wrong put pointer, expected %p got %p\n", buffer + 4, pssb->base.pptr); + ok(pssb->base.epptr == buffer + 16, "wrong put end, expected %p got %p\n", buffer + 16, pssb->base.epptr); + ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); + call_func1(p_strstream_vbase_dtor, &ios1); + ok(ios1.base_ios.sb == NULL, "expected %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, ios1.base_ios.state); + + ios1.base1.extract_delim = ios1.base1.count = 0xcdcdcdcd; + ios1.base2.unknown = 0xcdcdcdcd; + memset(&ios1.base_ios, 0xcd, sizeof(ios)); + pios = call_func3(p_strstream_copy_ctor, &ios2, &ios1, TRUE); + ok(pios == &ios2, "wrong return, expected %p got %p\n", &ios2, pios); + ok(ios2.base1.extract_delim == 0, "expected 0 got %d\n", ios2.base1.extract_delim); + ok(ios2.base1.count == 0, "expected 0 got %d\n", ios2.base1.count); + ok(ios2.base2.unknown == 0, "expected 0 got %d\n", ios2.base2.unknown); + ok(ios2.base_ios.sb == ios1.base_ios.sb, "expected %p got %p\n", ios1.base_ios.sb, ios2.base_ios.sb); + ok(ios2.base_ios.state == 0xcdcdcdc9, "expected %d got %d\n", 0xcdcdcdc9, ios2.base_ios.state); + ok(ios2.base_ios.delbuf == 0, "expected 0 got %d\n", ios2.base_ios.delbuf); + ok(ios2.base_ios.tie == ios1.base_ios.tie, "expected %p got %p\n", ios1.base_ios.tie, ios2.base_ios.tie); + ok(ios2.base_ios.flags == 0xcdcdcdcd, "expected %x got %x\n", 0xcdcdcdcd, ios2.base_ios.flags); + ok(ios2.base_ios.precision == (char) 0xcd, "expected -51 got %d\n", ios2.base_ios.precision); + ok(ios2.base_ios.fill == (char) 0xcd, "expected -51 got %d\n", ios2.base_ios.fill); + ok(ios2.base_ios.width == (char) 0xcd, "expected -51 got %d\n", ios2.base_ios.width); + ok(ios2.base_ios.do_lock == -1, "expected -1 got %d\n", ios2.base_ios.do_lock); + call_func1(p_strstream_vbase_dtor, &ios2); + ios2.base1.extract_delim = ios2.base1.count = 0xabababab; + ios2.base2.unknown = 0xabababab; + memset(&ios2.base_ios, 0xab, sizeof(ios)); + ios2.base_ios.delbuf = 0; + pos = ios2.base_ios.tie; + pios = call_func3(p_strstream_copy_ctor, &ios2, &ios1, FALSE); + ok(pios == &ios2, "wrong return, expected %p got %p\n", &ios2, pios); + ok(ios2.base1.extract_delim == 0, "expected 0 got %d\n", ios2.base1.extract_delim); + ok(ios2.base1.count == 0, "expected 0 got %d\n", ios2.base1.count); + ok(ios2.base2.unknown == 0, "expected 0 got %d\n", ios2.base2.unknown); + ok(ios2.base_ios.sb == ios1.base_ios.sb, "expected %p got %p\n", ios1.base_ios.sb, ios2.base_ios.sb); + ok(ios2.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base_ios.state); + ok(ios2.base_ios.delbuf == 0, "expected 0 got %d\n", ios2.base_ios.delbuf); + ok(ios2.base_ios.tie == pos, "expected %p got %p\n", pos, ios2.base_ios.tie); + ok(ios2.base_ios.flags == 0xabababab, "expected %x got %x\n", 0xabababab, ios2.base_ios.flags); + ok(ios2.base_ios.precision == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base_ios.precision); + ok(ios2.base_ios.fill == (char) 0xab, "expected -85 got %d\n", ios2.base_ios.fill); + ok(ios2.base_ios.width == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base_ios.width); + ok(ios2.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base_ios.do_lock); + call_func1(p_strstream_dtor, &ios2.base_ios); + + /* assignment */ + ios2.base1.extract_delim = ios2.base1.count = 0xabababab; + ios2.base2.unknown = 0xabababab; + memset(&ios2.base_ios, 0xab, sizeof(ios)); + ios2.base_ios.delbuf = 0; + pios = call_func2(p_strstream_assign, &ios2, &ios1); + ok(ios2.base1.extract_delim == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base1.extract_delim); + ok(ios2.base1.count == 0, "expected 0 got %d\n", ios2.base1.count); + ok(ios2.base2.unknown == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base2.unknown); + ok(ios2.base_ios.sb == ios1.base_ios.sb, "expected %p got %p\n", ios1.base_ios.sb, ios2.base_ios.sb); + ok(ios2.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ios2.base_ios.state); + ok(ios2.base_ios.delbuf == 0, "expected 0 got %d\n", ios2.base_ios.delbuf); + ok(ios2.base_ios.tie == NULL, "expected %p got %p\n", NULL, ios2.base_ios.tie); + ok(ios2.base_ios.flags == 0, "expected 0 got %x\n", ios2.base_ios.flags); + ok(ios2.base_ios.precision == 6, "expected 6 got %d\n", ios2.base_ios.precision); + ok(ios2.base_ios.fill == ' ', "expected 32 got %d\n", ios2.base_ios.fill); + ok(ios2.base_ios.width == 0, "expected 0 got %d\n", ios2.base_ios.width); + ok(ios2.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base_ios.do_lock); +} + static void test_Iostream_init(void) { ios ios_obj; @@ -6954,6 +7309,7 @@ START_TEST(msvcirt) test_istream_withassign(); test_istrstream(); test_iostream(); + test_strstream(); test_Iostream_init(); test_std_streams(); -- 2.7.4 From matellanesivan at gmail.com Fri Oct 21 12:34:03 2016 From: matellanesivan at gmail.com (=?UTF-8?q?Iv=C3=A1n=20Matellanes?=) Date: Fri, 21 Oct 2016 19:34:03 +0200 Subject: [3/4] msvcirt: Add a partial implementation of class stdiostream. In-Reply-To: <1477071244-13290-1-git-send-email-matellanesivan@gmail.com> References: <1477071244-13290-1-git-send-email-matellanesivan@gmail.com> Message-ID: <1477071244-13290-3-git-send-email-matellanesivan@gmail.com> Signed-off-by: Iván Matellanes --- dlls/msvcirt/msvcirt.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ dlls/msvcirt/msvcirt.spec | 34 +++++++++++++++++----------------- dlls/msvcrt20/msvcrt20.spec | 34 +++++++++++++++++----------------- dlls/msvcrt40/msvcrt40.spec | 34 +++++++++++++++++----------------- 4 files changed, 95 insertions(+), 51 deletions(-) diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index 9c36e69..1c1e469 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -197,6 +197,8 @@ extern const vtable_ptr MSVCP_istrstream_vtable; extern const vtable_ptr MSVCP_iostream_vtable; /* ??_7strstream@@6B@ */ extern const vtable_ptr MSVCP_strstream_vtable; +/* ??_7stdiostream@@6B@ */ +extern const vtable_ptr MSVCP_stdiostream_vtable; #ifndef __GNUC__ void __asm_dummy_vtables(void) { @@ -267,6 +269,8 @@ void __asm_dummy_vtables(void) { VTABLE_ADD_FUNC(iostream_vector_dtor)); __ASM_VTABLE(strstream, VTABLE_ADD_FUNC(iostream_vector_dtor)); + __ASM_VTABLE(stdiostream, + VTABLE_ADD_FUNC(iostream_vector_dtor)); #ifndef __GNUC__ } #endif @@ -283,9 +287,11 @@ const int ostream_vbtable[] = {0, VBTABLE_ENTRY(ostream, FIELD_OFFSET(ostream, v /* ??_8istrstream@@7B@ */ const int istream_vbtable[] = {0, VBTABLE_ENTRY(istream, FIELD_OFFSET(istream, vbtable), ios)}; /* ??_8iostream@@7Bistream@@@ */ +/* ??_8stdiostream@@7Bistream@@@ */ /* ??_8strstream@@7Bistream@@@ */ const int iostream_vbtable_istream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base1), ios)}; /* ??_8iostream@@7Bostream@@@ */ +/* ??_8stdiostream@@7Bostream@@@ */ /* ??_8strstream@@7Bostream@@@ */ const int iostream_vbtable_ostream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base2), ios)}; @@ -310,6 +316,9 @@ DEFINE_RTTI_DATA4(iostream, sizeof(iostream), DEFINE_RTTI_DATA4(strstream, sizeof(iostream), &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVstrstream@@") +DEFINE_RTTI_DATA4(stdiostream, sizeof(iostream), + &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, + &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVstdiostream@@") /* ?cin@@3Vistream_withassign@@A */ struct { @@ -4138,6 +4147,8 @@ iostream* __thiscall iostream_copy_ctor(iostream *this, const iostream *copy, BO /* ??1iostream@@UAE at XZ */ /* ??1iostream@@UEAA at XZ */ +/* ??1stdiostream@@UAE at XZ */ +/* ??1stdiostream@@UEAA at XZ */ /* ??1strstream@@UAE at XZ */ /* ??1strstream@@UEAA at XZ */ DEFINE_THISCALL_WRAPPER(iostream_dtor, 4) @@ -4164,6 +4175,8 @@ iostream* __thiscall iostream_assign_sb(iostream *this, streambuf *sb) /* ??4iostream@@IAEAAV0 at AAV0@@Z */ /* ??4iostream@@IEAAAEAV0 at AEAV0@@Z */ +/* ??4stdiostream@@QAEAAV0 at AAV0@@Z */ +/* ??4stdiostream@@QEAAAEAV0 at AEAV0@@Z */ /* ??4strstream@@QAEAAV0 at ABV0@@Z */ /* ??4strstream@@QEAAAEAV0 at AEBV0@@Z */ DEFINE_THISCALL_WRAPPER(iostream_assign, 8) @@ -4174,6 +4187,8 @@ iostream* __thiscall iostream_assign(iostream *this, const iostream *rhs) /* ??_Diostream@@QAEXXZ */ /* ??_Diostream@@QEAAXXZ */ +/* ??_Dstdiostream@@QAEXXZ */ +/* ??_Dstdiostream@@QEAAXXZ */ /* ??_Dstrstream@@QAEXXZ */ /* ??_Dstrstream@@QEAAXXZ */ DEFINE_THISCALL_WRAPPER(iostream_vbase_dtor, 4) @@ -4188,6 +4203,7 @@ void __thiscall iostream_vbase_dtor(iostream *this) } /* ??_Eiostream@@UAEPAXI at Z */ +/* ??_Estdiostream@@UAEPAXI at Z */ /* ??_Estrstream@@UAEPAXI at Z */ DEFINE_THISCALL_WRAPPER(iostream_vector_dtor, 8) iostream* __thiscall iostream_vector_dtor(ios *base, unsigned int flags) @@ -4212,6 +4228,7 @@ iostream* __thiscall iostream_vector_dtor(ios *base, unsigned int flags) } /* ??_Giostream@@UAEPAXI at Z */ +/* ??_Gstdiostream@@UAEPAXI at Z */ /* ??_Gstrstream@@UAEPAXI at Z */ DEFINE_THISCALL_WRAPPER(iostream_scalar_dtor, 8) iostream* __thiscall iostream_scalar_dtor(ios *base, unsigned int flags) @@ -4323,6 +4340,32 @@ char* __thiscall strstream_str(iostream *this) return strstreambuf_str(strstream_rdbuf(this)); } +/* ??0stdiostream@@QAE at ABV0@@Z */ +/* ??0stdiostream@@QEAA at AEBV0@@Z */ +DEFINE_THISCALL_WRAPPER(stdiostream_copy_ctor, 12) +iostream* __thiscall stdiostream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init) +{ + FIXME("(%p %p %d) stub\n", this, copy, virt_init); + return this; +} + +/* ??0stdiostream@@QAE at PAU_iobuf@@@Z */ +/* ??0stdiostream@@QEAA at PEAU_iobuf@@@Z */ +DEFINE_THISCALL_WRAPPER(stdiostream_file_ctor, 12) +iostream* __thiscall stdiostream_file_ctor(iostream *this, FILE *file, BOOL virt_init) +{ + FIXME("(%p %p %d) stub\n", this, file, virt_init); + return this; +} + +/* ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ */ +/* ?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ */ +DEFINE_THISCALL_WRAPPER(stdiostream_rdbuf, 4) +stdiobuf* __thiscall stdiostream_rdbuf(const iostream *this) +{ + return (stdiobuf*) istream_get_ios(&this->base1)->sb; +} + /* ??0Iostream_init@@QAE at AAVios@@H at Z */ /* ??0Iostream_init@@QEAA at AEAVios@@H at Z */ DEFINE_THISCALL_WRAPPER(Iostream_init_ios_ctor, 12) @@ -4479,6 +4522,7 @@ static void init_io(void *base) init_istrstream_rtti(base); init_iostream_rtti(base); init_strstream_rtti(base); + init_stdiostream_rtti(base); #endif if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) { diff --git a/dlls/msvcirt/msvcirt.spec b/dlls/msvcirt/msvcirt.spec index 557185d..2e5154c 100644 --- a/dlls/msvcirt/msvcirt.spec +++ b/dlls/msvcirt/msvcirt.spec @@ -102,10 +102,10 @@ @ cdecl -arch=win64 ??0stdiobuf@@QEAA at AEBV0@@Z(ptr ptr) stdiobuf_copy_ctor @ thiscall -arch=win32 ??0stdiobuf@@QAE at PAU_iobuf@@@Z(ptr ptr) stdiobuf_file_ctor @ cdecl -arch=win64 ??0stdiobuf@@QEAA at PEAU_iobuf@@@Z(ptr ptr) stdiobuf_file_ctor -@ stub -arch=win32 ??0stdiostream@@QAE at ABV0@@Z # __thiscall stdiostream::stdiostream(class stdiostream const &) -@ stub -arch=win64 ??0stdiostream@@QEAA at AEBV0@@Z -@ stub -arch=win32 ??0stdiostream@@QAE at PAU_iobuf@@@Z # __thiscall stdiostream::stdiostream(struct _iobuf *) -@ stub -arch=win64 ??0stdiostream@@QEAA at PEAU_iobuf@@@Z +@ thiscall -arch=win32 ??0stdiostream@@QAE at ABV0@@Z(ptr ptr long) stdiostream_copy_ctor +@ cdecl -arch=win64 ??0stdiostream@@QEAA at AEBV0@@Z(ptr ptr long) stdiostream_copy_ctor +@ thiscall -arch=win32 ??0stdiostream@@QAE at PAU_iobuf@@@Z(ptr ptr long) stdiostream_file_ctor +@ cdecl -arch=win64 ??0stdiostream@@QEAA at PEAU_iobuf@@@Z(ptr ptr long) stdiostream_file_ctor @ thiscall -arch=win32 ??0streambuf@@IAE at PADH@Z(ptr ptr long) streambuf_reserve_ctor @ cdecl -arch=win64 ??0streambuf@@IEAA at PEADH@Z(ptr ptr long) streambuf_reserve_ctor @ thiscall -arch=win32 ??0streambuf@@IAE at XZ(ptr) streambuf_ctor @@ -162,8 +162,8 @@ @ cdecl -arch=win64 ??1ostrstream@@UEAA at XZ(ptr) ostream_dtor @ thiscall -arch=win32 ??1stdiobuf@@UAE at XZ(ptr) stdiobuf_dtor @ cdecl -arch=win64 ??1stdiobuf@@UEAA at XZ(ptr) stdiobuf_dtor -@ stub -arch=win32 ??1stdiostream@@UAE at XZ # virtual __thiscall stdiostream::~stdiostream(void) -@ stub -arch=win64 ??1stdiostream@@UEAA at XZ +@ thiscall -arch=win32 ??1stdiostream@@UAE at XZ(ptr) iostream_dtor +@ cdecl -arch=win64 ??1stdiostream@@UEAA at XZ(ptr) iostream_dtor @ thiscall -arch=win32 ??1streambuf@@UAE at XZ(ptr) streambuf_dtor @ cdecl -arch=win64 ??1streambuf@@UEAA at XZ(ptr) streambuf_dtor @ thiscall -arch=win32 ??1strstream@@UAE at XZ(ptr) iostream_dtor @@ -216,8 +216,8 @@ @ cdecl -arch=win64 ??4ostrstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) ostream_assign @ thiscall -arch=win32 ??4stdiobuf@@QAEAAV0 at ABV0@@Z(ptr ptr) stdiobuf_assign @ cdecl -arch=win64 ??4stdiobuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) stdiobuf_assign -@ stub -arch=win32 ??4stdiostream@@QAEAAV0 at AAV0@@Z # class stdiostream & __thiscall stdiostream::operator=(class stdiostream &) -@ stub -arch=win64 ??4stdiostream@@QEAAAEAV0 at AEAV0@@Z +@ thiscall -arch=win32 ??4stdiostream@@QAEAAV0 at AAV0@@Z(ptr ptr) iostream_assign +@ cdecl -arch=win64 ??4stdiostream@@QEAAAEAV0 at AEAV0@@Z(ptr ptr) iostream_assign @ thiscall -arch=win32 ??4streambuf@@QAEAAV0 at ABV0@@Z(ptr ptr) streambuf_assign @ cdecl -arch=win64 ??4streambuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) streambuf_assign @ thiscall -arch=win32 ??4strstream@@QAEAAV0 at AAV0@@Z(ptr ptr) iostream_assign @@ -317,7 +317,7 @@ @ extern ??_7ostream_withassign@@6B@ MSVCP_ostream_withassign_vtable @ extern ??_7ostrstream@@6B@ MSVCP_ostrstream_vtable @ extern ??_7stdiobuf@@6B@ MSVCP_stdiobuf_vtable -# @ extern ??_7stdiostream@@6B@ # const stdiostream::`vftable' +@ extern ??_7stdiostream@@6B@ MSVCP_stdiostream_vtable @ extern ??_7streambuf@@6B@ MSVCP_streambuf_vtable @ extern ??_7strstream@@6B@ MSVCP_strstream_vtable @ extern ??_7strstreambuf@@6B@ MSVCP_strstreambuf_vtable @@ -333,8 +333,8 @@ @ extern ??_8ostream@@7B@ ostream_vbtable @ extern ??_8ostream_withassign@@7B@ ostream_vbtable @ extern ??_8ostrstream@@7B@ ostream_vbtable -# @ extern ??_8stdiostream@@7Bistream@@@ # const stdiostream::`vbtable'{for `istream'} -# @ extern ??_8stdiostream@@7Bostream@@@ # const stdiostream::`vbtable'{for `ostream'} +@ extern ??_8stdiostream@@7Bistream@@@ iostream_vbtable_istream +@ extern ??_8stdiostream@@7Bostream@@@ iostream_vbtable_ostream @ extern ??_8strstream@@7Bistream@@@ iostream_vbtable_istream @ extern ??_8strstream@@7Bostream@@@ iostream_vbtable_ostream @ stub -arch=win32 ??_Dfstream@@QAEXXZ # void __thiscall fstream::`vbase destructor'(void) @@ -357,8 +357,8 @@ @ cdecl -arch=win64 ??_Dostream_withassign@@QEAAXXZ(ptr) ostream_vbase_dtor @ thiscall -arch=win32 ??_Dostrstream@@QAEXXZ(ptr) ostream_vbase_dtor @ cdecl -arch=win64 ??_Dostrstream@@QEAAXXZ(ptr) ostream_vbase_dtor -@ stub -arch=win32 ??_Dstdiostream@@QAEXXZ # void __thiscall stdiostream::`vbase destructor'(void) -@ stub -arch=win64 ??_Dstdiostream@@QEAAXXZ +@ thiscall -arch=win32 ??_Dstdiostream@@QAEXXZ(ptr) iostream_vbase_dtor +@ cdecl -arch=win64 ??_Dstdiostream@@QEAAXXZ(ptr) iostream_vbase_dtor @ thiscall -arch=win32 ??_Dstrstream@@QAEXXZ(ptr) iostream_vbase_dtor @ cdecl -arch=win64 ??_Dstrstream@@QEAAXXZ(ptr) iostream_vbase_dtor @ thiscall -arch=win32 ??_Eexception@@UAEPAXI at Z(ptr long) MSVCP_exception_vector_dtor @@ -376,7 +376,7 @@ @ thiscall -arch=win32 ??_Eostream_withassign@@UAEPAXI at Z(ptr long) ostream_vector_dtor @ thiscall -arch=win32 ??_Eostrstream@@UAEPAXI at Z(ptr long) ostream_vector_dtor @ thiscall -arch=win32 ??_Estdiobuf@@UAEPAXI at Z(ptr long) stdiobuf_vector_dtor -@ stub -arch=win32 ??_Estdiostream@@UAEPAXI at Z # virtual void * __thiscall stdiostream::`vector deleting destructor'(unsigned int) +@ thiscall -arch=win32 ??_Estdiostream@@UAEPAXI at Z(ptr long) iostream_vector_dtor @ thiscall -arch=win32 ??_Estreambuf@@UAEPAXI at Z(ptr long) streambuf_vector_dtor @ thiscall -arch=win32 ??_Estrstream@@UAEPAXI at Z(ptr long) iostream_vector_dtor @ thiscall -arch=win32 ??_Estrstreambuf@@UAEPAXI at Z(ptr long) strstreambuf_vector_dtor @@ -395,7 +395,7 @@ @ thiscall -arch=win32 ??_Gostream_withassign@@UAEPAXI at Z(ptr long) ostream_scalar_dtor @ thiscall -arch=win32 ??_Gostrstream@@UAEPAXI at Z(ptr long) ostream_scalar_dtor @ thiscall -arch=win32 ??_Gstdiobuf@@UAEPAXI at Z(ptr long) stdiobuf_scalar_dtor -@ stub -arch=win32 ??_Gstdiostream@@UAEPAXI at Z # virtual void * __thiscall stdiostream::`scalar deleting destructor'(unsigned int) +@ thiscall -arch=win32 ??_Gstdiostream@@UAEPAXI at Z(ptr long) iostream_scalar_dtor @ thiscall -arch=win32 ??_Gstreambuf@@UAEPAXI at Z(ptr long) streambuf_scalar_dtor @ thiscall -arch=win32 ??_Gstrstream@@UAEPAXI at Z(ptr long) iostream_scalar_dtor @ thiscall -arch=win32 ??_Gstrstreambuf@@UAEPAXI at Z(ptr long) strstreambuf_scalar_dtor @@ -625,8 +625,8 @@ @ stub -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ @ thiscall -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ(ptr) ostrstream_rdbuf @ cdecl -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) ostrstream_rdbuf -@ stub -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ # class stdiobuf * __thiscall stdiostream::rdbuf(void)const -@ stub -arch=win64 ?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ +@ thiscall -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ(ptr) stdiostream_rdbuf +@ cdecl -arch=win64 ?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ(ptr) stdiostream_rdbuf @ thiscall -arch=win32 ?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ(ptr) strstream_rdbuf @ cdecl -arch=win64 ?rdbuf at strstream@@QEBAPEAVstrstreambuf@@XZ(ptr) strstream_rdbuf @ thiscall -arch=win32 ?rdstate at ios@@QBEHXZ(ptr) ios_rdstate diff --git a/dlls/msvcrt20/msvcrt20.spec b/dlls/msvcrt20/msvcrt20.spec index 4059a47..2187843 100644 --- a/dlls/msvcrt20/msvcrt20.spec +++ b/dlls/msvcrt20/msvcrt20.spec @@ -92,10 +92,10 @@ @ cdecl -arch=win64 ??0stdiobuf@@QEAA at AEBV0@@Z(ptr ptr) msvcirt.??0stdiobuf@@QEAA at AEBV0@@Z @ thiscall -arch=win32 ??0stdiobuf@@QAE at PAU_iobuf@@@Z(ptr ptr) msvcirt.??0stdiobuf@@QAE at PAU_iobuf@@@Z @ cdecl -arch=win64 ??0stdiobuf@@QEAA at PEAU_iobuf@@@Z(ptr ptr) msvcirt.??0stdiobuf@@QEAA at PEAU_iobuf@@@Z -@ stub -arch=win32 ??0stdiostream@@QAE at ABV0@@Z -@ stub -arch=win64 ??0stdiostream@@QEAA at AEBV0@@Z -@ stub -arch=win32 ??0stdiostream@@QAE at PAU_iobuf@@@Z -@ stub -arch=win64 ??0stdiostream@@QEAA at PEAU_iobuf@@@Z +@ thiscall -arch=win32 ??0stdiostream@@QAE at ABV0@@Z(ptr ptr long) msvcirt.??0stdiostream@@QAE at ABV0@@Z +@ cdecl -arch=win64 ??0stdiostream@@QEAA at AEBV0@@Z(ptr ptr long) msvcirt.??0stdiostream@@QEAA at AEBV0@@Z +@ thiscall -arch=win32 ??0stdiostream@@QAE at PAU_iobuf@@@Z(ptr ptr long) msvcirt.??0stdiostream@@QAE at PAU_iobuf@@@Z +@ cdecl -arch=win64 ??0stdiostream@@QEAA at PEAU_iobuf@@@Z(ptr ptr long) msvcirt.??0stdiostream@@QEAA at PEAU_iobuf@@@Z @ thiscall -arch=win32 ??0streambuf@@IAE at PADH@Z(ptr ptr long) msvcirt.??0streambuf@@IAE at PADH@Z @ cdecl -arch=win64 ??0streambuf@@IEAA at PEADH@Z(ptr ptr long) msvcirt.??0streambuf@@IEAA at PEADH@Z @ thiscall -arch=win32 ??0streambuf@@IAE at XZ(ptr) msvcirt.??0streambuf@@IAE at XZ @@ -146,8 +146,8 @@ @ cdecl -arch=win64 ??1ostrstream@@UEAA at XZ(ptr) msvcirt.??1ostrstream@@UEAA at XZ @ thiscall -arch=win32 ??1stdiobuf@@UAE at XZ(ptr) msvcirt.??1stdiobuf@@UAE at XZ @ cdecl -arch=win64 ??1stdiobuf@@UEAA at XZ(ptr) msvcirt.??1stdiobuf@@UEAA at XZ -@ stub -arch=win32 ??1stdiostream@@UAE at XZ -@ stub -arch=win64 ??1stdiostream@@UEAA at XZ +@ thiscall -arch=win32 ??1stdiostream@@UAE at XZ(ptr) msvcirt.??1stdiostream@@UAE at XZ +@ cdecl -arch=win64 ??1stdiostream@@UEAA at XZ(ptr) msvcirt.??1stdiostream@@UEAA at XZ @ thiscall -arch=win32 ??1streambuf@@UAE at XZ(ptr) msvcirt.??1streambuf@@UAE at XZ @ cdecl -arch=win64 ??1streambuf@@UEAA at XZ(ptr) msvcirt.??1streambuf@@UEAA at XZ @ thiscall -arch=win32 ??1strstream@@UAE at XZ(ptr) msvcirt.??1strstream@@UAE at XZ @@ -200,8 +200,8 @@ @ cdecl -arch=win64 ??4ostrstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4ostrstream@@QEAAAEAV0 at AEBV0@@Z @ thiscall -arch=win32 ??4stdiobuf@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4stdiobuf@@QAEAAV0 at ABV0@@Z @ cdecl -arch=win64 ??4stdiobuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4stdiobuf@@QEAAAEAV0 at AEBV0@@Z -@ stub -arch=win32 ??4stdiostream@@QAEAAV0 at AAV0@@Z -@ stub -arch=win64 ??4stdiostream@@QEAAAEAV0 at AEAV0@@Z +@ thiscall -arch=win32 ??4stdiostream@@QAEAAV0 at AAV0@@Z(ptr ptr) msvcirt.??4stdiostream@@QAEAAV0 at AAV0@@Z +@ cdecl -arch=win64 ??4stdiostream@@QEAAAEAV0 at AEAV0@@Z(ptr ptr) msvcirt.??4stdiostream@@QEAAAEAV0 at AEAV0@@Z @ thiscall -arch=win32 ??4streambuf@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4streambuf@@QAEAAV0 at ABV0@@Z @ cdecl -arch=win64 ??4streambuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4streambuf@@QEAAAEAV0 at AEBV0@@Z @ thiscall -arch=win32 ??4strstream@@QAEAAV0 at AAV0@@Z(ptr ptr) msvcirt.??4strstream@@QAEAAV0 at AAV0@@Z @@ -299,7 +299,7 @@ @ extern ??_7ostream_withassign@@6B@ msvcirt.??_7ostream_withassign@@6B@ @ extern ??_7ostrstream@@6B@ msvcirt.??_7ostrstream@@6B@ @ extern ??_7stdiobuf@@6B@ msvcirt.??_7stdiobuf@@6B@ -# @ extern ??_7stdiostream@@6B@ +@ extern ??_7stdiostream@@6B@ msvcirt.??_7stdiostream@@6B@ @ extern ??_7streambuf@@6B@ msvcirt.??_7streambuf@@6B@ @ extern ??_7strstream@@6B@ msvcirt.??_7strstream@@6B@ @ extern ??_7strstreambuf@@6B@ msvcirt.??_7strstreambuf@@6B@ @@ -315,8 +315,8 @@ @ extern ??_8ostream@@7B@ msvcirt.??_8ostream@@7B@ @ extern ??_8ostream_withassign@@7B@ msvcirt.??_8ostream_withassign@@7B@ @ extern ??_8ostrstream@@7B@ msvcirt.??_8ostrstream@@7B@ -# @ extern ??_8stdiostream@@7Bistream@@@ -# @ extern ??_8stdiostream@@7Bostream@@@ +@ extern ??_8stdiostream@@7Bistream@@@ msvcirt.??_8stdiostream@@7Bistream@@@ +@ extern ??_8stdiostream@@7Bostream@@@ msvcirt.??_8stdiostream@@7Bostream@@@ @ extern ??_8strstream@@7Bistream@@@ msvcirt.??_8strstream@@7Bistream@@@ @ extern ??_8strstream@@7Bostream@@@ msvcirt.??_8strstream@@7Bostream@@@ @ stub -arch=win32 ??_Dfstream@@QAEXXZ @@ -339,8 +339,8 @@ @ cdecl -arch=win64 ??_Dostream_withassign@@QEAAXXZ(ptr) msvcirt.??_Dostream_withassign@@QEAAXXZ @ thiscall -arch=win32 ??_Dostrstream@@QAEXXZ(ptr) msvcirt.??_Dostrstream@@QAEXXZ @ cdecl -arch=win64 ??_Dostrstream@@QEAAXXZ(ptr) msvcirt.??_Dostrstream@@QEAAXXZ -@ stub -arch=win32 ??_Dstdiostream@@QAEXXZ -@ stub -arch=win64 ??_Dstdiostream@@QEAAXXZ +@ thiscall -arch=win32 ??_Dstdiostream@@QAEXXZ(ptr) msvcirt.??_Dstdiostream@@QAEXXZ +@ cdecl -arch=win64 ??_Dstdiostream@@QEAAXXZ(ptr) msvcirt.??_Dstdiostream@@QEAAXXZ @ thiscall -arch=win32 ??_Dstrstream@@QAEXXZ(ptr) msvcirt.??_Dstrstream@@QAEXXZ @ cdecl -arch=win64 ??_Dstrstream@@QEAAXXZ(ptr) msvcirt.??_Dstrstream@@QEAAXXZ @ stub -arch=win32 ??_EIostream_init@@QAEPAXI at Z @@ -357,7 +357,7 @@ @ thiscall -arch=win32 ??_Eostream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Eostream_withassign@@UAEPAXI at Z @ thiscall -arch=win32 ??_Eostrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Eostrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estdiobuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estdiobuf@@UAEPAXI at Z -@ stub -arch=win32 ??_Estdiostream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Estdiostream@@UAEPAXI at Z(ptr long) msvcirt.??_Estdiostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estreambuf@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Estrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estrstreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estrstreambuf@@UAEPAXI at Z @@ -375,7 +375,7 @@ @ thiscall -arch=win32 ??_Gostream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Gostream_withassign@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gostrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gostrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstdiobuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstdiobuf@@UAEPAXI at Z -@ stub -arch=win32 ??_Gstdiostream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Gstdiostream@@UAEPAXI at Z(ptr long) msvcirt.??_Gstdiostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstreambuf@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gstrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstrstreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstrstreambuf@@UAEPAXI at Z @@ -611,8 +611,8 @@ @ stub -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ @ thiscall -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ @ cdecl -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ -@ stub -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ -@ stub -arch=win64 ?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ +@ thiscall -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ(ptr) msvcirt.?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ +@ cdecl -arch=win64 ?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ(ptr) msvcirt.?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ @ thiscall -arch=win32 ?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ @ cdecl -arch=win64 ?rdbuf at strstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at strstream@@QEBAPEAVstrstreambuf@@XZ @ thiscall -arch=win32 ?rdstate at ios@@QBEHXZ(ptr) msvcirt.?rdstate at ios@@QBEHXZ diff --git a/dlls/msvcrt40/msvcrt40.spec b/dlls/msvcrt40/msvcrt40.spec index 40b6eab..a1e14f8 100644 --- a/dlls/msvcrt40/msvcrt40.spec +++ b/dlls/msvcrt40/msvcrt40.spec @@ -114,10 +114,10 @@ @ cdecl -arch=win64 ??0stdiobuf@@QEAA at AEBV0@@Z(ptr ptr) msvcirt.??0stdiobuf@@QEAA at AEBV0@@Z @ thiscall -arch=win32 ??0stdiobuf@@QAE at PAU_iobuf@@@Z(ptr ptr) msvcirt.??0stdiobuf@@QAE at PAU_iobuf@@@Z @ cdecl -arch=win64 ??0stdiobuf@@QEAA at PEAU_iobuf@@@Z(ptr ptr) msvcirt.??0stdiobuf@@QEAA at PEAU_iobuf@@@Z -@ stub -arch=win32 ??0stdiostream@@QAE at ABV0@@Z -@ stub -arch=win64 ??0stdiostream@@QEAA at AEBV0@@Z -@ stub -arch=win32 ??0stdiostream@@QAE at PAU_iobuf@@@Z -@ stub -arch=win64 ??0stdiostream@@QEAA at PEAU_iobuf@@@Z +@ thiscall -arch=win32 ??0stdiostream@@QAE at ABV0@@Z(ptr ptr long) msvcirt.??0stdiostream@@QAE at ABV0@@Z +@ cdecl -arch=win64 ??0stdiostream@@QEAA at AEBV0@@Z(ptr ptr long) msvcirt.??0stdiostream@@QEAA at AEBV0@@Z +@ thiscall -arch=win32 ??0stdiostream@@QAE at PAU_iobuf@@@Z(ptr ptr long) msvcirt.??0stdiostream@@QAE at PAU_iobuf@@@Z +@ cdecl -arch=win64 ??0stdiostream@@QEAA at PEAU_iobuf@@@Z(ptr ptr long) msvcirt.??0stdiostream@@QEAA at PEAU_iobuf@@@Z @ thiscall -arch=win32 ??0streambuf@@IAE at PADH@Z(ptr ptr long) msvcirt.??0streambuf@@IAE at PADH@Z @ cdecl -arch=win64 ??0streambuf@@IEAA at PEADH@Z(ptr ptr long) msvcirt.??0streambuf@@IEAA at PEADH@Z @ thiscall -arch=win32 ??0streambuf@@IAE at XZ(ptr) msvcirt.??0streambuf@@IAE at XZ @@ -178,8 +178,8 @@ @ cdecl -arch=win64 ??1ostrstream@@UEAA at XZ(ptr) msvcirt.??1ostrstream@@UEAA at XZ @ thiscall -arch=win32 ??1stdiobuf@@UAE at XZ(ptr) msvcirt.??1stdiobuf@@UAE at XZ @ cdecl -arch=win64 ??1stdiobuf@@UEAA at XZ(ptr) msvcirt.??1stdiobuf@@UEAA at XZ -@ stub -arch=win32 ??1stdiostream@@UAE at XZ -@ stub -arch=win64 ??1stdiostream@@UEAA at XZ +@ thiscall -arch=win32 ??1stdiostream@@UAE at XZ(ptr) msvcirt.??1stdiostream@@UAE at XZ +@ cdecl -arch=win64 ??1stdiostream@@UEAA at XZ(ptr) msvcirt.??1stdiostream@@UEAA at XZ @ thiscall -arch=win32 ??1streambuf@@UAE at XZ(ptr) msvcirt.??1streambuf@@UAE at XZ @ cdecl -arch=win64 ??1streambuf@@UEAA at XZ(ptr) msvcirt.??1streambuf@@UEAA at XZ @ thiscall -arch=win32 ??1strstream@@UAE at XZ(ptr) msvcirt.??1strstream@@UAE at XZ @@ -244,8 +244,8 @@ @ cdecl -arch=win64 ??4ostrstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4ostrstream@@QEAAAEAV0 at AEBV0@@Z @ thiscall -arch=win32 ??4stdiobuf@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4stdiobuf@@QAEAAV0 at ABV0@@Z @ cdecl -arch=win64 ??4stdiobuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4stdiobuf@@QEAAAEAV0 at AEBV0@@Z -@ stub -arch=win32 ??4stdiostream@@QAEAAV0 at AAV0@@Z -@ stub -arch=win64 ??4stdiostream@@QEAAAEAV0 at AEAV0@@Z +@ thiscall -arch=win32 ??4stdiostream@@QAEAAV0 at AAV0@@Z(ptr ptr) msvcirt.??4stdiostream@@QAEAAV0 at AAV0@@Z +@ cdecl -arch=win64 ??4stdiostream@@QEAAAEAV0 at AEAV0@@Z(ptr ptr) msvcirt.??4stdiostream@@QEAAAEAV0 at AEAV0@@Z @ thiscall -arch=win32 ??4streambuf@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4streambuf@@QAEAAV0 at ABV0@@Z @ cdecl -arch=win64 ??4streambuf@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4streambuf@@QEAAAEAV0 at AEBV0@@Z @ thiscall -arch=win32 ??4strstream@@QAEAAV0 at AAV0@@Z(ptr ptr) msvcirt.??4strstream@@QAEAAV0 at AAV0@@Z @@ -352,7 +352,7 @@ @ extern ??_7ostream_withassign@@6B@ msvcirt.??_7ostream_withassign@@6B@ @ extern ??_7ostrstream@@6B@ msvcirt.??_7ostrstream@@6B@ @ extern ??_7stdiobuf@@6B@ msvcirt.??_7stdiobuf@@6B@ -# @ extern ??_7stdiostream@@6B@ +@ extern ??_7stdiostream@@6B@ msvcirt.??_7stdiostream@@6B@ @ extern ??_7streambuf@@6B@ msvcirt.??_7streambuf@@6B@ @ extern ??_7strstream@@6B@ msvcirt.??_7strstream@@6B@ @ extern ??_7strstreambuf@@6B@ msvcirt.??_7strstreambuf@@6B@ @@ -368,8 +368,8 @@ @ extern ??_8ostream@@7B@ msvcirt.??_8ostream@@7B@ @ extern ??_8ostream_withassign@@7B@ msvcirt.??_8ostream_withassign@@7B@ @ extern ??_8ostrstream@@7B@ msvcirt.??_8ostrstream@@7B@ -# @ extern ??_8stdiostream@@7Bistream@@@ -# @ extern ??_8stdiostream@@7Bostream@@@ +@ extern ??_8stdiostream@@7Bistream@@@ msvcirt.??_8stdiostream@@7Bistream@@@ +@ extern ??_8stdiostream@@7Bostream@@@ msvcirt.??_8stdiostream@@7Bostream@@@ @ extern ??_8strstream@@7Bistream@@@ msvcirt.??_8strstream@@7Bistream@@@ @ extern ??_8strstream@@7Bostream@@@ msvcirt.??_8strstream@@7Bostream@@@ @ stub -arch=win32 ??_Dfstream@@QAEXXZ @@ -392,8 +392,8 @@ @ cdecl -arch=win64 ??_Dostream_withassign@@QEAAXXZ(ptr) msvcirt.??_Dostream_withassign@@QEAAXXZ @ thiscall -arch=win32 ??_Dostrstream@@QAEXXZ(ptr) msvcirt.??_Dostrstream@@QAEXXZ @ cdecl -arch=win64 ??_Dostrstream@@QEAAXXZ(ptr) msvcirt.??_Dostrstream@@QEAAXXZ -@ stub -arch=win32 ??_Dstdiostream@@QAEXXZ -@ stub -arch=win64 ??_Dstdiostream@@QEAAXXZ +@ thiscall -arch=win32 ??_Dstdiostream@@QAEXXZ(ptr) msvcirt.??_Dstdiostream@@QAEXXZ +@ cdecl -arch=win64 ??_Dstdiostream@@QEAAXXZ(ptr) msvcirt.??_Dstdiostream@@QEAAXXZ @ thiscall -arch=win32 ??_Dstrstream@@QAEXXZ(ptr) msvcirt.??_Dstrstream@@QAEXXZ @ cdecl -arch=win64 ??_Dstrstream@@QEAAXXZ(ptr) msvcirt.??_Dstrstream@@QEAAXXZ @ stub -arch=win32 ??_EIostream_init@@QAEPAXI at Z @@ -415,7 +415,7 @@ @ thiscall -arch=win32 ??_Eostream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Eostream_withassign@@UAEPAXI at Z @ thiscall -arch=win32 ??_Eostrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Eostrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estdiobuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estdiobuf@@UAEPAXI at Z -@ stub -arch=win32 ??_Estdiostream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Estdiostream@@UAEPAXI at Z(ptr long) msvcirt.??_Estdiostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estreambuf@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Estrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Estrstreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Estrstreambuf@@UAEPAXI at Z @@ -438,7 +438,7 @@ @ thiscall -arch=win32 ??_Gostream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Gostream_withassign@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gostrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gostrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstdiobuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstdiobuf@@UAEPAXI at Z -@ stub -arch=win32 ??_Gstdiostream@@UAEPAXI at Z +@ thiscall -arch=win32 ??_Gstdiostream@@UAEPAXI at Z(ptr long) msvcirt.??_Gstdiostream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstreambuf@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gstrstream@@UAEPAXI at Z @ thiscall -arch=win32 ??_Gstrstreambuf@@UAEPAXI at Z(ptr long) msvcirt.??_Gstrstreambuf@@UAEPAXI at Z @@ -682,8 +682,8 @@ @ stub -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ @ thiscall -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ @ cdecl -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ -@ stub -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ -@ stub -arch=win64 ?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ +@ thiscall -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ(ptr) msvcirt.?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ +@ cdecl -arch=win64 ?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ(ptr) msvcirt.?rdbuf at stdiostream@@QEBAPEAVstdiobuf@@XZ @ thiscall -arch=win32 ?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at strstream@@QBEPAVstrstreambuf@@XZ @ cdecl -arch=win64 ?rdbuf at strstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at strstream@@QEBAPEAVstrstreambuf@@XZ @ thiscall -arch=win32 ?rdstate at ios@@QBEHXZ(ptr) msvcirt.?rdstate at ios@@QBEHXZ -- 2.7.4 From matellanesivan at gmail.com Fri Oct 21 12:34:04 2016 From: matellanesivan at gmail.com (=?UTF-8?q?Iv=C3=A1n=20Matellanes?=) Date: Fri, 21 Oct 2016 19:34:04 +0200 Subject: [4/4] msvcirt: Implement stdiostream constructors. In-Reply-To: <1477071244-13290-1-git-send-email-matellanesivan@gmail.com> References: <1477071244-13290-1-git-send-email-matellanesivan@gmail.com> Message-ID: <1477071244-13290-4-git-send-email-matellanesivan@gmail.com> Signed-off-by: Iván Matellanes --- dlls/msvcirt/msvcirt.c | 15 +++- dlls/msvcirt/tests/msvcirt.c | 177 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 4 deletions(-) diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index 1c1e469..7f48346 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -4345,8 +4345,8 @@ char* __thiscall strstream_str(iostream *this) DEFINE_THISCALL_WRAPPER(stdiostream_copy_ctor, 12) iostream* __thiscall stdiostream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init) { - FIXME("(%p %p %d) stub\n", this, copy, virt_init); - return this; + TRACE("(%p %p %d)\n", this, copy, virt_init); + return iostream_internal_copy_ctor(this, copy, &MSVCP_stdiostream_vtable, virt_init); } /* ??0stdiostream@@QAE at PAU_iobuf@@@Z */ @@ -4354,8 +4354,15 @@ iostream* __thiscall stdiostream_copy_ctor(iostream *this, const iostream *copy, DEFINE_THISCALL_WRAPPER(stdiostream_file_ctor, 12) iostream* __thiscall stdiostream_file_ctor(iostream *this, FILE *file, BOOL virt_init) { - FIXME("(%p %p %d) stub\n", this, file, virt_init); - return this; + stdiobuf *stb = MSVCRT_operator_new(sizeof(stdiobuf)); + + TRACE("(%p %p %d)\n", this, file, virt_init); + + if (stb) { + stdiobuf_file_ctor(stb, file); + return iostream_internal_sb_ctor(this, &stb->base, &MSVCP_stdiostream_vtable, virt_init); + } + return iostream_internal_sb_ctor(this, NULL, &MSVCP_stdiostream_vtable, virt_init); } /* ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ */ diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c index de5af0d..2234abf 100644 --- a/dlls/msvcirt/tests/msvcirt.c +++ b/dlls/msvcirt/tests/msvcirt.c @@ -412,6 +412,13 @@ static void (*__thiscall p_strstream_dtor)(ios*); static void (*__thiscall p_strstream_vbase_dtor)(iostream*); static iostream* (*__thiscall p_strstream_assign)(iostream*, const iostream*); +/* stdiostream */ +static iostream* (*__thiscall p_stdiostream_copy_ctor)(iostream*, const iostream*, BOOL); +static iostream* (*__thiscall p_stdiostream_file_ctor)(iostream*, FILE*, BOOL); +static void (*__thiscall p_stdiostream_dtor)(ios*); +static void (*__thiscall p_stdiostream_vbase_dtor)(iostream*); +static iostream* (*__thiscall p_stdiostream_assign)(iostream*, const iostream*); + /* Iostream_init */ static void* (*__thiscall p_Iostream_init_ios_ctor)(void*, ios*, int); @@ -696,6 +703,12 @@ static BOOL init(void) SET(p_strstream_vbase_dtor, "??_Dstrstream@@QEAAXXZ"); SET(p_strstream_assign, "??4strstream@@QEAAAEAV0 at AEAV0@@Z"); + SET(p_stdiostream_copy_ctor, "??0stdiostream@@QEAA at AEBV0@@Z"); + SET(p_stdiostream_file_ctor, "??0stdiostream@@QEAA at PEAU_iobuf@@@Z"); + SET(p_stdiostream_dtor, "??1stdiostream@@UEAA at XZ"); + SET(p_stdiostream_vbase_dtor, "??_Dstdiostream@@QEAAXXZ"); + SET(p_stdiostream_assign, "??4stdiostream@@QEAAAEAV0 at AEAV0@@Z"); + SET(p_Iostream_init_ios_ctor, "??0Iostream_init@@QEAA at AEAVios@@H at Z"); } else { p_operator_new = (void*)GetProcAddress(msvcrt, "??2 at YAPAXI@Z"); @@ -897,6 +910,12 @@ static BOOL init(void) SET(p_strstream_vbase_dtor, "??_Dstrstream@@QAEXXZ"); SET(p_strstream_assign, "??4strstream@@QAEAAV0 at AAV0@@Z"); + SET(p_stdiostream_copy_ctor, "??0stdiostream@@QAE at ABV0@@Z"); + SET(p_stdiostream_file_ctor, "??0stdiostream@@QAE at PAU_iobuf@@@Z"); + SET(p_stdiostream_dtor, "??1stdiostream@@UAE at XZ"); + SET(p_stdiostream_vbase_dtor, "??_Dstdiostream@@QAEXXZ"); + SET(p_stdiostream_assign, "??4stdiostream@@QAEAAV0 at AAV0@@Z"); + SET(p_Iostream_init_ios_ctor, "??0Iostream_init@@QAE at AAVios@@H at Z"); } SET(p_ios_static_lock, "?x_lockc at ios@@0U_CRT_CRITICAL_SECTION@@A"); @@ -7013,6 +7032,163 @@ static void test_strstream(void) ok(ios2.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base_ios.do_lock); } +static void test_stdiostream(void) +{ + iostream ios1, ios2, *pios; + ostream *pos; + stdiobuf *pstb; + FILE *file; + const char filename[] = "stdiostream_test"; + + memset(&ios1, 0xab, sizeof(iostream)); + memset(&ios2, 0xab, sizeof(iostream)); + + file = fopen(filename, "w+"); + ok(file != NULL, "Couldn't open the file named '%s'\n", filename); + + /* constructors/destructors */ + pios = call_func3(p_stdiostream_file_ctor, &ios1, file, TRUE); + pstb = (stdiobuf*) ios1.base_ios.sb; + ok(pios == &ios1, "wrong return, expected %p got %p\n", &ios1, pios); + ok(ios1.base1.extract_delim == 0, "expected 0 got %d\n", ios1.base1.extract_delim); + ok(ios1.base1.count == 0, "expected 0 got %d\n", ios1.base1.count); + ok(ios1.base2.unknown == 0, "expected 0 got %d\n", ios1.base2.unknown); + ok(ios1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ios1.base_ios.state); + ok(ios1.base_ios.delbuf == 1, "expected 1 got %d\n", ios1.base_ios.delbuf); + ok(ios1.base_ios.tie == NULL, "expected %p got %p\n", NULL, ios1.base_ios.tie); + ok(ios1.base_ios.flags == FLAGS_skipws, "expected %x got %x\n", FLAGS_skipws, ios1.base_ios.flags); + ok(ios1.base_ios.precision == 6, "expected 6 got %d\n", ios1.base_ios.precision); + ok(ios1.base_ios.fill == ' ', "expected 32 got %d\n", ios1.base_ios.fill); + ok(ios1.base_ios.width == 0, "expected 0 got %d\n", ios1.base_ios.width); + ok(ios1.base_ios.do_lock == -1, "expected -1 got %d\n", ios1.base_ios.do_lock); + ok(pstb->file == file, "expected %p, got %p\n", file, pstb->file); + ok(pstb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pstb->base.allocated); + ok(pstb->base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", pstb->base.unbuffered); + ok(pstb->base.base == NULL, "wrong buffer, expected %p got %p\n", NULL, pstb->base.base); + ok(pstb->base.ebuf == NULL, "wrong buffer end, expected %p got %p\n", NULL, pstb->base.ebuf); + ok(pstb->base.do_lock == -1, "expected -1 got %d\n", pstb->base.do_lock); + call_func1(p_stdiostream_vbase_dtor, &ios1); + ok(ios1.base_ios.sb == NULL, "expected %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, ios1.base_ios.state); + ios1.base1.extract_delim = ios1.base1.count = 0xabababab; + ios1.base2.unknown = 0xabababab; + memset(&ios1.base_ios, 0xab, sizeof(ios)); + ios1.base_ios.delbuf = 0; + pios = call_func3(p_stdiostream_file_ctor, &ios1, file, FALSE); + pstb = (stdiobuf*) ios1.base_ios.sb; + ok(pios == &ios1, "wrong return, expected %p got %p\n", &ios1, pios); + ok(ios1.base1.extract_delim == 0, "expected 0 got %d\n", ios1.base1.extract_delim); + ok(ios1.base1.count == 0, "expected 0 got %d\n", ios1.base1.count); + ok(ios1.base2.unknown == 0, "expected 0 got %d\n", ios1.base2.unknown); + ok(ios1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.state); + ok(ios1.base_ios.delbuf == 1, "expected 1 got %d\n", ios1.base_ios.delbuf); + ok(ios1.base_ios.tie == ios2.base_ios.tie, "expected %p got %p\n", ios2.base_ios.tie, ios1.base_ios.tie); + ok(ios1.base_ios.flags == 0xabababab, "expected %x got %x\n", 0xabababab, ios1.base_ios.flags); + ok(ios1.base_ios.precision == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.precision); + ok(ios1.base_ios.fill == (char) 0xab, "expected -85 got %d\n", ios1.base_ios.fill); + ok(ios1.base_ios.width == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.width); + ok(ios1.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.do_lock); + ok(pstb->file == file, "expected %p, got %p\n", file, pstb->file); + ok(pstb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pstb->base.allocated); + ok(pstb->base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", pstb->base.unbuffered); + ok(pstb->base.base == NULL, "wrong buffer, expected %p got %p\n", NULL, pstb->base.base); + ok(pstb->base.ebuf == NULL, "wrong buffer end, expected %p got %p\n", NULL, pstb->base.ebuf); + ok(pstb->base.do_lock == -1, "expected -1 got %d\n", pstb->base.do_lock); + call_func1(p_stdiostream_dtor, &ios1.base_ios); + ok(ios1.base_ios.sb == &pstb->base, "expected %p got %p\n", &pstb->base, ios1.base_ios.sb); + ok(ios1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, ios1.base_ios.state); + call_func1(p_stdiobuf_dtor, pstb); + p_operator_delete(pstb); + memset(&ios1, 0xab, sizeof(iostream)); + pios = call_func3(p_stdiostream_file_ctor, &ios1, NULL, TRUE); + pstb = (stdiobuf*) ios1.base_ios.sb; + ok(pios == &ios1, "wrong return, expected %p got %p\n", &ios1, pios); + ok(ios1.base1.extract_delim == 0, "expected 0 got %d\n", ios1.base1.extract_delim); + ok(ios1.base1.count == 0, "expected 0 got %d\n", ios1.base1.count); + ok(ios1.base2.unknown == 0, "expected 0 got %d\n", ios1.base2.unknown); + ok(ios1.base_ios.sb != NULL, "expected not %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ios1.base_ios.state); + ok(ios1.base_ios.delbuf == 1, "expected 1 got %d\n", ios1.base_ios.delbuf); + ok(ios1.base_ios.tie == NULL, "expected %p got %p\n", NULL, ios1.base_ios.tie); + ok(ios1.base_ios.flags == FLAGS_skipws, "expected %x got %x\n", FLAGS_skipws, ios1.base_ios.flags); + ok(ios1.base_ios.precision == 6, "expected 6 got %d\n", ios1.base_ios.precision); + ok(ios1.base_ios.fill == ' ', "expected 32 got %d\n", ios1.base_ios.fill); + ok(ios1.base_ios.width == 0, "expected 0 got %d\n", ios1.base_ios.width); + ok(ios1.base_ios.do_lock == -1, "expected -1 got %d\n", ios1.base_ios.do_lock); + ok(pstb->file == NULL, "expected %p, got %p\n", NULL, pstb->file); + ok(pstb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pstb->base.allocated); + ok(pstb->base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", pstb->base.unbuffered); + ok(pstb->base.base == NULL, "wrong buffer, expected %p got %p\n", NULL, pstb->base.base); + ok(pstb->base.ebuf == NULL, "wrong buffer end, expected %p got %p\n", NULL, pstb->base.ebuf); + ok(pstb->base.do_lock == -1, "expected -1 got %d\n", pstb->base.do_lock); + call_func1(p_stdiostream_vbase_dtor, &ios1); + ok(ios1.base_ios.sb == NULL, "expected %p got %p\n", NULL, ios1.base_ios.sb); + ok(ios1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, ios1.base_ios.state); + + ios1.base1.extract_delim = ios1.base1.count = 0xcdcdcdcd; + ios1.base2.unknown = 0xcdcdcdcd; + memset(&ios1.base_ios, 0xcd, sizeof(ios)); + pios = call_func3(p_stdiostream_copy_ctor, &ios2, &ios1, TRUE); + ok(pios == &ios2, "wrong return, expected %p got %p\n", &ios2, pios); + ok(ios2.base1.extract_delim == 0, "expected 0 got %d\n", ios2.base1.extract_delim); + ok(ios2.base1.count == 0, "expected 0 got %d\n", ios2.base1.count); + ok(ios2.base2.unknown == 0, "expected 0 got %d\n", ios2.base2.unknown); + ok(ios2.base_ios.sb == ios1.base_ios.sb, "expected %p got %p\n", ios1.base_ios.sb, ios2.base_ios.sb); + ok(ios2.base_ios.state == 0xcdcdcdc9, "expected %d got %d\n", 0xcdcdcdc9, ios2.base_ios.state); + ok(ios2.base_ios.delbuf == 0, "expected 0 got %d\n", ios2.base_ios.delbuf); + ok(ios2.base_ios.tie == ios1.base_ios.tie, "expected %p got %p\n", ios1.base_ios.tie, ios2.base_ios.tie); + ok(ios2.base_ios.flags == 0xcdcdcdcd, "expected %x got %x\n", 0xcdcdcdcd, ios2.base_ios.flags); + ok(ios2.base_ios.precision == (char) 0xcd, "expected -51 got %d\n", ios2.base_ios.precision); + ok(ios2.base_ios.fill == (char) 0xcd, "expected -51 got %d\n", ios2.base_ios.fill); + ok(ios2.base_ios.width == (char) 0xcd, "expected -51 got %d\n", ios2.base_ios.width); + ok(ios2.base_ios.do_lock == -1, "expected -1 got %d\n", ios2.base_ios.do_lock); + call_func1(p_stdiostream_vbase_dtor, &ios2); + ios2.base1.extract_delim = ios2.base1.count = 0xabababab; + ios2.base2.unknown = 0xabababab; + memset(&ios2.base_ios, 0xab, sizeof(ios)); + ios2.base_ios.delbuf = 0; + pos = ios2.base_ios.tie; + pios = call_func3(p_stdiostream_copy_ctor, &ios2, &ios1, FALSE); + ok(pios == &ios2, "wrong return, expected %p got %p\n", &ios2, pios); + ok(ios2.base1.extract_delim == 0, "expected 0 got %d\n", ios2.base1.extract_delim); + ok(ios2.base1.count == 0, "expected 0 got %d\n", ios2.base1.count); + ok(ios2.base2.unknown == 0, "expected 0 got %d\n", ios2.base2.unknown); + ok(ios2.base_ios.sb == ios1.base_ios.sb, "expected %p got %p\n", ios1.base_ios.sb, ios2.base_ios.sb); + ok(ios2.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base_ios.state); + ok(ios2.base_ios.delbuf == 0, "expected 0 got %d\n", ios2.base_ios.delbuf); + ok(ios2.base_ios.tie == pos, "expected %p got %p\n", pos, ios2.base_ios.tie); + ok(ios2.base_ios.flags == 0xabababab, "expected %x got %x\n", 0xabababab, ios2.base_ios.flags); + ok(ios2.base_ios.precision == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base_ios.precision); + ok(ios2.base_ios.fill == (char) 0xab, "expected -85 got %d\n", ios2.base_ios.fill); + ok(ios2.base_ios.width == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base_ios.width); + ok(ios2.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base_ios.do_lock); + call_func1(p_stdiostream_dtor, &ios2.base_ios); + + /* assignment */ + ios2.base1.extract_delim = ios2.base1.count = 0xabababab; + ios2.base2.unknown = 0xabababab; + memset(&ios2.base_ios, 0xab, sizeof(ios)); + ios2.base_ios.delbuf = 0; + pios = call_func2(p_stdiostream_assign, &ios2, &ios1); + ok(ios2.base1.extract_delim == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base1.extract_delim); + ok(ios2.base1.count == 0, "expected 0 got %d\n", ios2.base1.count); + ok(ios2.base2.unknown == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base2.unknown); + ok(ios2.base_ios.sb == ios1.base_ios.sb, "expected %p got %p\n", ios1.base_ios.sb, ios2.base_ios.sb); + ok(ios2.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ios2.base_ios.state); + ok(ios2.base_ios.delbuf == 0, "expected 0 got %d\n", ios2.base_ios.delbuf); + ok(ios2.base_ios.tie == NULL, "expected %p got %p\n", NULL, ios2.base_ios.tie); + ok(ios2.base_ios.flags == 0, "expected 0 got %x\n", ios2.base_ios.flags); + ok(ios2.base_ios.precision == 6, "expected 6 got %d\n", ios2.base_ios.precision); + ok(ios2.base_ios.fill == ' ', "expected 32 got %d\n", ios2.base_ios.fill); + ok(ios2.base_ios.width == 0, "expected 0 got %d\n", ios2.base_ios.width); + ok(ios2.base_ios.do_lock == 0xabababab, "expected %d got %d\n", 0xabababab, ios2.base_ios.do_lock); + + fclose(file); + ok(_unlink(filename) == 0, "Couldn't unlink file named '%s'\n", filename); +} + static void test_Iostream_init(void) { ios ios_obj; @@ -7310,6 +7486,7 @@ START_TEST(msvcirt) test_istrstream(); test_iostream(); test_strstream(); + test_stdiostream(); test_Iostream_init(); test_std_streams(); -- 2.7.4 From jacek at codeweavers.com Fri Oct 21 12:52:24 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Fri, 21 Oct 2016 19:52:24 +0200 Subject: mshtml/tests: Use EqualRect() to compare RECTs. In-Reply-To: <20161020081908.GA23821@redhat.com> References: <20161020081908.GA23821@redhat.com> Message-ID: Signed-off-by: Jacek Caban -------------- next part -------------- An HTML attachment was scrubbed... URL: From jacek at codeweavers.com Fri Oct 21 12:52:32 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Fri, 21 Oct 2016 19:52:32 +0200 Subject: mshtml: Use EqualRect() to compare RECTs. In-Reply-To: <20161020082406.GB23821@redhat.com> References: <20161020082406.GB23821@redhat.com> Message-ID: <8fe3f463-7690-df82-5e60-b9aeeaf82d34@codeweavers.com> Signed-off-by: Jacek Caban -------------- next part -------------- An HTML attachment was scrubbed... URL: From piotr at codeweavers.com Fri Oct 21 13:23:24 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Fri, 21 Oct 2016 20:23:24 +0200 Subject: [1/4] msvcirt: Add a partial implementation of class strstream. In-Reply-To: <1477071244-13290-1-git-send-email-matellanesivan@gmail.com> References: <1477071244-13290-1-git-send-email-matellanesivan@gmail.com> Message-ID: <6ee01e03-0cfc-e0bd-b353-da0c7d22186b@codeweavers.com> Signed-off-by: Piotr Caban From piotr at codeweavers.com Fri Oct 21 13:23:28 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Fri, 21 Oct 2016 20:23:28 +0200 Subject: [2/4] msvcirt: Implement strstream constructors. In-Reply-To: <1477071244-13290-2-git-send-email-matellanesivan@gmail.com> References: <1477071244-13290-2-git-send-email-matellanesivan@gmail.com> Message-ID: <010962d0-fd5a-5389-9c41-9e5ec17adc8e@codeweavers.com> Signed-off-by: Piotr Caban From piotr at codeweavers.com Fri Oct 21 13:23:31 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Fri, 21 Oct 2016 20:23:31 +0200 Subject: [3/4] msvcirt: Add a partial implementation of class stdiostream. In-Reply-To: <1477071244-13290-3-git-send-email-matellanesivan@gmail.com> References: <1477071244-13290-3-git-send-email-matellanesivan@gmail.com> Message-ID: Signed-off-by: Piotr Caban From piotr at codeweavers.com Fri Oct 21 13:23:38 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Fri, 21 Oct 2016 20:23:38 +0200 Subject: [4/4] msvcirt: Implement stdiostream constructors. In-Reply-To: <1477071244-13290-4-git-send-email-matellanesivan@gmail.com> References: <1477071244-13290-4-git-send-email-matellanesivan@gmail.com> Message-ID: <007d9375-9e70-da2e-ef5f-7a700247c834@codeweavers.com> Signed-off-by: Piotr Caban From carlo.bramix at libero.it Sat Oct 22 04:30:35 2016 From: carlo.bramix at libero.it (Carlo Bramini) Date: Sat, 22 Oct 2016 11:30:35 +0200 (CEST) Subject: [PATCH] MSI: remove useless code. Message-ID: <1747463070.4193641477128635984.JavaMail.httpd@webmail-19.iol.local> Actually there is no need to do such calculation, because sprintfW() already returns the number of emitted characters. Sincerely. Signed-off-by: Carlo Bramini -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: msi.txt URL: From lukasz.wojnilowicz at gmail.com Sat Oct 22 00:32:39 2016 From: lukasz.wojnilowicz at gmail.com (=?UTF-8?q?=C5=81ukasz=20Wojni=C5=82owicz?=) Date: Sat, 22 Oct 2016 07:32:39 +0200 Subject: [website] Polish translation for release 1.9.21 Message-ID: <1477114359-3253-1-git-send-email-lukasz.wojnilowicz@gmail.com> --- news/pl/2016101401.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 news/pl/2016101401.xml diff --git a/news/pl/2016101401.xml b/news/pl/2016101401.xml new file mode 100644 index 0000000..bd68ea2 --- /dev/null +++ b/news/pl/2016101401.xml @@ -0,0 +1,15 @@ + +Październik 14, 2016 +Wydano Wine 1.9.21 + +

Wydanie rozwojowe Wine 1.9.21 jest już dostępne.

+

Co nowego w tym wydaniu: +

    +
  • Początkowa wersja mini sterownika HID.
  • +
  • Obsługa list w elemenie RichEdit.
  • +
  • Ulepszenia do tacki systemowej.
  • +
  • Rozmaite poprawki błędów.
  • +
+

Źródło jest już dostępne. +Paczki binarne są w trakcie budowy i ukażą się wkrótce w przeznaczonych dla nich pobieralniach. +

-- 2.7.4 From h.boizard at gmail.com Sat Oct 22 17:58:25 2016 From: h.boizard at gmail.com (Hadrien Boizard) Date: Sun, 23 Oct 2016 00:58:25 +0200 Subject: [PATCH] mshtml: Use EqualRect() instead of memcmp() to compare RECTs. Message-ID: Signed-off-by: Hadrien Boizard --- dlls/mshtml/pluginhost.c | 2 +- dlls/mshtml/view.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-mshtml-Use-EqualRect-instead-of-memcmp-to-compare-RE.patch Type: text/x-patch Size: 1134 bytes Desc: not available URL: From h.boizard at gmail.com Sat Oct 22 17:59:06 2016 From: h.boizard at gmail.com (Hadrien Boizard) Date: Sun, 23 Oct 2016 00:59:06 +0200 Subject: [PATCH] mshtml/tests: Use EqualRect() instead of memcmp() to compare RECTs. Message-ID: Signed-off-by: Hadrien Boizard --- dlls/mshtml/tests/activex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-mshtml-tests-Use-EqualRect-instead-of-memcmp-to-comp.patch Type: text/x-patch Size: 1028 bytes Desc: not available URL: From ken at codeweavers.com Sun Oct 23 13:03:20 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:20 -0500 Subject: [PATCH 01/15] winemac: Allocate clipboard data as GMEM_FIXED. Message-ID: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index 2082cad..72aed3a 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -461,7 +461,7 @@ static HANDLE convert_text(const void *src, int src_len, UINT src_cp, UINT dest_ if (dest_cp == (UINT)-1) { - handle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, wstr_len * sizeof(WCHAR)); + handle = GlobalAlloc(GMEM_FIXED, wstr_len * sizeof(WCHAR)); if (handle && (p = GlobalLock(handle))) { memcpy(p, wstr, wstr_len * sizeof(WCHAR)); @@ -475,7 +475,7 @@ static HANDLE convert_text(const void *src, int src_len, UINT src_cp, UINT dest_ len = WideCharToMultiByte(dest_cp, 0, wstr, wstr_len, NULL, 0, NULL, NULL); if (!wstr_len || wstr[wstr_len - 1]) len += 1; - handle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len); + handle = GlobalAlloc(GMEM_FIXED, len); if (handle && (p = GlobalLock(handle))) { @@ -568,7 +568,7 @@ static HGLOBAL create_dib_from_bitmap(HBITMAP hBmp) /* Allocate the packed DIB */ TRACE("\tAllocating packed DIB of size %d\n", cPackedSize); - hPackedDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cPackedSize); + hPackedDIB = GlobalAlloc(GMEM_FIXED, cPackedSize); if (!hPackedDIB) { WARN("Could not allocate packed DIB!\n"); @@ -660,7 +660,7 @@ static HANDLE import_clipboard_data(CFDataRef data) LPVOID p; /* Turn on the DDESHARE flag to enable shared 32 bit memory */ - data_handle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len); + data_handle = GlobalAlloc(GMEM_FIXED, len); if (!data_handle) return NULL; @@ -716,7 +716,7 @@ static HANDLE import_bmp_to_dib(CFDataRef data) BYTE* p; len -= sizeof(*bfh); - ret = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len); + ret = GlobalAlloc(GMEM_FIXED, len); if (!ret || !(p = GlobalLock(ret))) { GlobalFree(ret); @@ -779,7 +779,7 @@ static HANDLE import_enhmetafile_to_metafilepict(CFDataRef data) HANDLE hemf; METAFILEPICT *mfp; - if ((hmf = GlobalAlloc(0, sizeof(*mfp))) && (hemf = import_enhmetafile(data))) + if ((hmf = GlobalAlloc(GMEM_FIXED, sizeof(*mfp))) && (hemf = import_enhmetafile(data))) { ENHMETAHEADER header; HDC hdc = CreateCompatibleDC(0); @@ -823,7 +823,7 @@ static HANDLE import_metafilepict(CFDataRef data) TRACE("data %s\n", debugstr_cf(data)); - if (len >= sizeof(*mfp) && (ret = GlobalAlloc(0, sizeof(*mfp)))) + if (len >= sizeof(*mfp) && (ret = GlobalAlloc(GMEM_FIXED, sizeof(*mfp)))) { const BYTE *bytes = (const BYTE*)CFDataGetBytePtr(data); @@ -940,7 +940,7 @@ static HANDLE import_nsfilenames_to_hdrop(CFDataRef data) for (i = 0; i < count; i++) len += strlenW(paths[i]) + 1; - hdrop = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(*dropfiles) + len * sizeof(WCHAR)); + hdrop = GlobalAlloc(GMEM_FIXED, sizeof(*dropfiles) + len * sizeof(WCHAR)); if (!hdrop || !(dropfiles = GlobalLock(hdrop))) { WARN("failed to allocate HDROP\n"); @@ -1110,7 +1110,7 @@ static HANDLE import_utf8_to_unicodetext(CFDataRef data) dst[j] = 0; count = MultiByteToWideChar(CP_UTF8, 0, dst, -1, NULL, 0); - unicode_handle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, count * sizeof(WCHAR)); + unicode_handle = GlobalAlloc(GMEM_FIXED, count * sizeof(WCHAR)); if (unicode_handle) { @@ -1178,7 +1178,7 @@ static HANDLE import_utf16_to_unicodetext(CFDataRef data) new_lines++; } - if ((unicode_handle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (src_len + new_lines + 1) * sizeof(WCHAR)))) + if ((unicode_handle = GlobalAlloc(GMEM_FIXED, (src_len + new_lines + 1) * sizeof(WCHAR)))) { dst = GlobalLock(unicode_handle); -- 2.8.2 From ken at codeweavers.com Sun Oct 23 13:03:21 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:21 -0500 Subject: [PATCH 02/15] winemac: Convert old-Mac-style line breaks (CR) to Windows-style CRLF when importing UTF-16. In-Reply-To: <1477245814-49846-1-git-send-email-ken@codeweavers.com> References: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Message-ID: <1477245814-49846-2-git-send-email-ken@codeweavers.com> At least one Mac app, TextWrangler, puts UTF-16 data on the pasteboard with lines separated by CR (although it uses LF for the UTF-8 form of the same text). Other Mac apps handle it properly; we should, too. Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index 72aed3a..bdbd62e 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -1176,6 +1176,8 @@ static HANDLE import_utf16_to_unicodetext(CFDataRef data) { if (src[i] == '\n') new_lines++; + else if (src[i] == '\r' && (i + 1 >= src_len || src[i + 1] != '\n')) + new_lines++; } if ((unicode_handle = GlobalAlloc(GMEM_FIXED, (src_len + new_lines + 1) * sizeof(WCHAR)))) @@ -1188,6 +1190,9 @@ static HANDLE import_utf16_to_unicodetext(CFDataRef data) dst[j++] = '\r'; dst[j++] = src[i]; + + if (src[i] == '\r' && (i + 1 >= src_len || src[i + 1] != '\n')) + dst[j++] = '\n'; } dst[j] = 0; -- 2.8.2 From ken at codeweavers.com Sun Oct 23 13:03:22 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:22 -0500 Subject: [PATCH 03/15] winemac: Remove support for owner-displayed clipboard formats. In-Reply-To: <1477245814-49846-1-git-send-email-ken@codeweavers.com> References: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Message-ID: <1477245814-49846-3-git-send-email-ken@codeweavers.com> Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index bdbd62e..9b5490e 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -161,12 +161,7 @@ static const struct } builtin_format_ids[] = { { CF_DIF, CFSTR("org.winehq.builtin.dif"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_DSPBITMAP, CFSTR("org.winehq.builtin.dspbitmap"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_DSPENHMETAFILE, CFSTR("org.winehq.builtin.dspenhmetafile"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_DSPMETAFILEPICT, CFSTR("org.winehq.builtin.dspmetafilepict"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_DSPTEXT, CFSTR("org.winehq.builtin.dsptext"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_LOCALE, CFSTR("org.winehq.builtin.locale"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_OWNERDISPLAY, CFSTR("org.winehq.builtin.ownerdisplay"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_PALETTE, CFSTR("org.winehq.builtin.palette"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_PENDATA, CFSTR("org.winehq.builtin.pendata"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_RIFF, CFSTR("org.winehq.builtin.riff"), import_clipboard_data, export_clipboard_data, FALSE }, -- 2.8.2 From ken at codeweavers.com Sun Oct 23 13:03:23 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:23 -0500 Subject: [PATCH 04/15] winemac: Remove support for converting among standard clipboard formats. In-Reply-To: <1477245814-49846-1-git-send-email-ken@codeweavers.com> References: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Message-ID: <1477245814-49846-4-git-send-email-ken@codeweavers.com> User32 handles that now. Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 231 +++---------------------------------------- 1 file changed, 16 insertions(+), 215 deletions(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index 9b5490e..8737a56 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -73,18 +73,9 @@ typedef struct _WINE_CLIPFORMAT static HANDLE import_clipboard_data(CFDataRef data); static HANDLE import_bmp_to_bitmap(CFDataRef data); static HANDLE import_bmp_to_dib(CFDataRef data); -static HANDLE import_dib_to_bitmap(CFDataRef data); static HANDLE import_enhmetafile(CFDataRef data); -static HANDLE import_enhmetafile_to_metafilepict(CFDataRef data); static HANDLE import_metafilepict(CFDataRef data); -static HANDLE import_metafilepict_to_enhmetafile(CFDataRef data); static HANDLE import_nsfilenames_to_hdrop(CFDataRef data); -static HANDLE import_oemtext_to_text(CFDataRef data); -static HANDLE import_oemtext_to_unicodetext(CFDataRef data); -static HANDLE import_text_to_oemtext(CFDataRef data); -static HANDLE import_text_to_unicodetext(CFDataRef data); -static HANDLE import_unicodetext_to_oemtext(CFDataRef data); -static HANDLE import_unicodetext_to_text(CFDataRef data); static HANDLE import_utf8_to_oemtext(CFDataRef data); static HANDLE import_utf8_to_text(CFDataRef data); static HANDLE import_utf8_to_unicodetext(CFDataRef data); @@ -94,7 +85,6 @@ static HANDLE import_utf16_to_unicodetext(CFDataRef data); static CFDataRef export_clipboard_data(HANDLE data); static CFDataRef export_bitmap_to_bmp(HANDLE data); -static CFDataRef export_bitmap_to_dib(HANDLE data); static CFDataRef export_dib_to_bmp(HANDLE data); static CFDataRef export_enhmetafile(HANDLE data); static CFDataRef export_hdrop_to_filenames(HANDLE data); @@ -161,7 +151,9 @@ static const struct } builtin_format_ids[] = { { CF_DIF, CFSTR("org.winehq.builtin.dif"), import_clipboard_data, export_clipboard_data, FALSE }, + { CF_ENHMETAFILE, CFSTR("org.winehq.builtin.enhmetafile"), import_enhmetafile, export_enhmetafile, FALSE }, { CF_LOCALE, CFSTR("org.winehq.builtin.locale"), import_clipboard_data, export_clipboard_data, FALSE }, + { CF_METAFILEPICT, CFSTR("org.winehq.builtin.metafilepict"), import_metafilepict, export_metafilepict, FALSE }, { CF_PALETTE, CFSTR("org.winehq.builtin.palette"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_PENDATA, CFSTR("org.winehq.builtin.pendata"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_RIFF, CFSTR("org.winehq.builtin.riff"), import_clipboard_data, export_clipboard_data, FALSE }, @@ -169,50 +161,29 @@ static const struct { CF_TIFF, CFSTR("public.tiff"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_WAVE, CFSTR("com.microsoft.waveform-audio"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_UNICODETEXT, CFSTR("org.winehq.builtin.unicodetext"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_TEXT, CFSTR("org.winehq.builtin.unicodetext"), import_unicodetext_to_text, NULL, TRUE }, - { CF_OEMTEXT, CFSTR("org.winehq.builtin.unicodetext"), import_unicodetext_to_oemtext, NULL, TRUE }, - - { CF_TEXT, CFSTR("org.winehq.builtin.text"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_OEMTEXT, CFSTR("org.winehq.builtin.text"), import_text_to_oemtext, NULL, TRUE }, - { CF_UNICODETEXT, CFSTR("org.winehq.builtin.text"), import_text_to_unicodetext, NULL, TRUE }, - - { CF_OEMTEXT, CFSTR("org.winehq.builtin.oemtext"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_TEXT, CFSTR("org.winehq.builtin.oemtext"), import_oemtext_to_text, NULL, TRUE }, - { CF_UNICODETEXT, CFSTR("org.winehq.builtin.oemtext"), import_oemtext_to_unicodetext, NULL, TRUE }, - - { CF_TEXT, CFSTR("public.utf8-plain-text"), import_utf8_to_text, export_text_to_utf8, TRUE }, - { CF_OEMTEXT, CFSTR("public.utf8-plain-text"), import_utf8_to_oemtext, export_oemtext_to_utf8, TRUE }, - { CF_UNICODETEXT, CFSTR("public.utf8-plain-text"), import_utf8_to_unicodetext, export_unicodetext_to_utf8, TRUE }, - - { CF_TEXT, CFSTR("public.utf16-plain-text"), import_utf16_to_text, export_text_to_utf16, TRUE }, - { CF_OEMTEXT, CFSTR("public.utf16-plain-text"), import_utf16_to_oemtext, export_oemtext_to_utf16, TRUE }, - { CF_UNICODETEXT, CFSTR("public.utf16-plain-text"), import_utf16_to_unicodetext, export_unicodetext_to_utf16,TRUE }, - { CF_BITMAP, CFSTR("org.winehq.builtin.bitmap"), import_bmp_to_bitmap, export_bitmap_to_bmp, FALSE }, - { CF_DIB, CFSTR("org.winehq.builtin.bitmap"), import_bmp_to_dib, export_dib_to_bmp, TRUE }, - { CF_DIBV5, CFSTR("org.winehq.builtin.bitmap"), import_bmp_to_dib, export_dib_to_bmp, TRUE }, - - { CF_DIB, CFSTR("org.winehq.builtin.dib"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_BITMAP, CFSTR("org.winehq.builtin.dib"), import_dib_to_bitmap, export_bitmap_to_dib, TRUE }, - { CF_DIBV5, CFSTR("org.winehq.builtin.dib"), import_clipboard_data, export_clipboard_data, TRUE }, - - { CF_DIBV5, CFSTR("org.winehq.builtin.dibv5"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_BITMAP, CFSTR("org.winehq.builtin.dibv5"), import_dib_to_bitmap, export_bitmap_to_dib, TRUE }, - { CF_DIB, CFSTR("org.winehq.builtin.dibv5"), import_clipboard_data, export_clipboard_data, TRUE }, - { CF_BITMAP, CFSTR("com.microsoft.bmp"), import_bmp_to_bitmap, export_bitmap_to_bmp, TRUE }, + + { CF_DIB, CFSTR("org.winehq.builtin.dib"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_DIB, CFSTR("com.microsoft.bmp"), import_bmp_to_dib, export_dib_to_bmp, TRUE }, + + { CF_DIBV5, CFSTR("org.winehq.builtin.dibv5"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_DIBV5, CFSTR("com.microsoft.bmp"), import_bmp_to_dib, export_dib_to_bmp, TRUE }, { CF_HDROP, CFSTR("org.winehq.builtin.hdrop"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_HDROP, CFSTR("NSFilenamesPboardType"), import_nsfilenames_to_hdrop, export_hdrop_to_filenames, TRUE }, - { CF_ENHMETAFILE, CFSTR("org.winehq.builtin.enhmetafile"), import_enhmetafile, export_enhmetafile, FALSE }, - { CF_METAFILEPICT, CFSTR("org.winehq.builtin.enhmetafile"), import_enhmetafile_to_metafilepict, NULL, TRUE }, + { CF_OEMTEXT, CFSTR("org.winehq.builtin.oemtext"), import_clipboard_data, export_clipboard_data, FALSE }, + { CF_OEMTEXT, CFSTR("public.utf16-plain-text"), import_utf16_to_oemtext, export_oemtext_to_utf16, TRUE }, + { CF_OEMTEXT, CFSTR("public.utf8-plain-text"), import_utf8_to_oemtext, export_oemtext_to_utf8, TRUE }, - { CF_METAFILEPICT, CFSTR("org.winehq.builtin.metafilepict"), import_metafilepict, export_metafilepict, FALSE }, - { CF_ENHMETAFILE, CFSTR("org.winehq.builtin.metafilepict"), import_metafilepict_to_enhmetafile, NULL, TRUE }, + { CF_TEXT, CFSTR("org.winehq.builtin.text"), import_clipboard_data, export_clipboard_data, FALSE }, + { CF_TEXT, CFSTR("public.utf16-plain-text"), import_utf16_to_text, export_text_to_utf16, TRUE }, + { CF_TEXT, CFSTR("public.utf8-plain-text"), import_utf8_to_text, export_text_to_utf8, TRUE }, + + { CF_UNICODETEXT, CFSTR("org.winehq.builtin.unicodetext"), import_clipboard_data, export_clipboard_data, FALSE }, + { CF_UNICODETEXT, CFSTR("public.utf16-plain-text"), import_utf16_to_unicodetext, export_unicodetext_to_utf16,TRUE }, + { CF_UNICODETEXT, CFSTR("public.utf8-plain-text"), import_utf8_to_unicodetext, export_unicodetext_to_utf8, TRUE }, }; static const WCHAR wszRichTextFormat[] = {'R','i','c','h',' ','T','e','x','t',' ','F','o','r','m','a','t',0}; @@ -727,24 +698,6 @@ static HANDLE import_bmp_to_dib(CFDataRef data) /************************************************************************** - * import_dib_to_bitmap - * - * Import device-independent bitmap data, converting to CF_BITMAP format. - */ -static HANDLE import_dib_to_bitmap(CFDataRef data) -{ - HANDLE ret; - HANDLE dib = import_clipboard_data(data); - - ret = create_bitmap_from_dib(dib); - - GlobalFree(dib); - - return ret; -} - - -/************************************************************************** * import_enhmetafile * * Import enhanced metafile data, converting it to CF_ENHMETAFILE. @@ -764,48 +717,6 @@ static HANDLE import_enhmetafile(CFDataRef data) /************************************************************************** - * import_enhmetafile_to_metafilepict - * - * Import enhanced metafile data, converting it to CF_METAFILEPICT. - */ -static HANDLE import_enhmetafile_to_metafilepict(CFDataRef data) -{ - HANDLE ret = 0, hmf; - HANDLE hemf; - METAFILEPICT *mfp; - - if ((hmf = GlobalAlloc(GMEM_FIXED, sizeof(*mfp))) && (hemf = import_enhmetafile(data))) - { - ENHMETAHEADER header; - HDC hdc = CreateCompatibleDC(0); - unsigned int size = GetWinMetaFileBits(hemf, 0, NULL, MM_ISOTROPIC, hdc); - BYTE *bytes; - - bytes = HeapAlloc(GetProcessHeap(), 0, size); - if (bytes && GetEnhMetaFileHeader(hemf, sizeof(header), &header) && - GetWinMetaFileBits(hemf, size, bytes, MM_ISOTROPIC, hdc)) - { - mfp = GlobalLock(hmf); - mfp->mm = MM_ISOTROPIC; - mfp->xExt = header.rclFrame.right - header.rclFrame.left; - mfp->yExt = header.rclFrame.bottom - header.rclFrame.top; - mfp->hMF = SetMetaFileBitsEx(size, bytes); - GlobalUnlock(hmf); - - ret = hmf; - } - - if (hdc) DeleteDC(hdc); - HeapFree(GetProcessHeap(), 0, bytes); - DeleteEnhMetaFile(hemf); - } - - if (!ret) GlobalFree(hmf); - return ret; -} - - -/************************************************************************** * import_metafilepict * * Import metafile picture data, converting it to CF_METAFILEPICT. @@ -833,29 +744,6 @@ static HANDLE import_metafilepict(CFDataRef data) /************************************************************************** - * import_metafilepict_to_enhmetafile - * - * Import metafile picture data, converting it to CF_ENHMETAFILE. - */ -static HANDLE import_metafilepict_to_enhmetafile(CFDataRef data) -{ - HANDLE ret = 0; - CFIndex len = CFDataGetLength(data); - const METAFILEPICT *mfp; - - TRACE("data %s\n", debugstr_cf(data)); - - if (len >= sizeof(*mfp)) - { - mfp = (const METAFILEPICT*)CFDataGetBytePtr(data); - ret = SetWinMetaFileBits(len - sizeof(*mfp), (const BYTE*)(mfp + 1), NULL, mfp); - } - - return ret; -} - - -/************************************************************************** * import_nsfilenames_to_hdrop * * Import NSFilenamesPboardType data, converting the property-list- @@ -974,72 +862,6 @@ done: /************************************************************************** - * import_oemtext_to_text - * - * Import CF_OEMTEXT data, converting the string to CF_TEXT. - */ -static HANDLE import_oemtext_to_text(CFDataRef data) -{ - return convert_text(CFDataGetBytePtr(data), CFDataGetLength(data), CP_OEMCP, CP_ACP); -} - - -/************************************************************************** - * import_oemtext_to_unicodetext - * - * Import CF_OEMTEXT data, converting the string to CF_UNICODETEXT. - */ -static HANDLE import_oemtext_to_unicodetext(CFDataRef data) -{ - return convert_text(CFDataGetBytePtr(data), CFDataGetLength(data), CP_OEMCP, -1); -} - - -/************************************************************************** - * import_text_to_oemtext - * - * Import CF_TEXT data, converting the string to CF_OEMTEXT. - */ -static HANDLE import_text_to_oemtext(CFDataRef data) -{ - return convert_text(CFDataGetBytePtr(data), CFDataGetLength(data), CP_ACP, CP_OEMCP); -} - - -/************************************************************************** - * import_text_to_unicodetext - * - * Import CF_TEXT data, converting the string to CF_UNICODETEXT. - */ -static HANDLE import_text_to_unicodetext(CFDataRef data) -{ - return convert_text(CFDataGetBytePtr(data), CFDataGetLength(data), CP_ACP, -1); -} - - -/************************************************************************** - * import_unicodetext_to_oemtext - * - * Import a CF_UNICODETEXT string, converting the string to CF_OEMTEXT. - */ -static HANDLE import_unicodetext_to_oemtext(CFDataRef data) -{ - return convert_text(CFDataGetBytePtr(data), CFDataGetLength(data), -1, CP_OEMCP); -} - - -/************************************************************************** - * import_unicodetext_to_text - * - * Import a CF_UNICODETEXT string, converting the string to CF_TEXT. - */ -static HANDLE import_unicodetext_to_text(CFDataRef data) -{ - return convert_text(CFDataGetBytePtr(data), CFDataGetLength(data), -1, CP_ACP); -} - - -/************************************************************************** * import_utf8_to_oemtext * * Import a UTF-8 string, converting the string to CF_OEMTEXT. @@ -1242,27 +1064,6 @@ static CFDataRef export_bitmap_to_bmp(HANDLE data) /************************************************************************** - * export_bitmap_to_dib - * - * Export CF_BITMAP to a raw packed device-independent bitmap. - */ -static CFDataRef export_bitmap_to_dib(HANDLE data) -{ - CFDataRef ret = NULL; - HGLOBAL dib; - - dib = create_dib_from_bitmap(data); - if (dib) - { - ret = export_clipboard_data(dib); - GlobalFree(dib); - } - - return ret; -} - - -/************************************************************************** * export_codepage_to_utf8 * * Export string data in a specified codepage to UTF-8. -- 2.8.2 From ken at codeweavers.com Sun Oct 23 13:03:24 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:24 -0500 Subject: [PATCH 05/15] winemac: Don't export/import CF_BITMAP or CF_DIBV5 to/from a Mac-native data type. In-Reply-To: <1477245814-49846-1-git-send-email-ken@codeweavers.com> References: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Message-ID: <1477245814-49846-5-git-send-email-ken@codeweavers.com> The relevant Mac-native type, com.microsoft.bmp, is handled by CF_DIB and user32 handles the synthesis of CF_BITMAP and CF_DIBV5 from that. CF_BITMAP and CF_DIBV5 are still exported and imported with a Wine-specific type to preserve cross-prefix copy/paste fidelity. Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index 8737a56..b0c1e49 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -150,6 +150,8 @@ static const struct BOOL synthesized; } builtin_format_ids[] = { + { CF_BITMAP, CFSTR("org.winehq.builtin.bitmap"), import_bmp_to_bitmap, export_bitmap_to_bmp, FALSE }, + { CF_DIBV5, CFSTR("org.winehq.builtin.dibv5"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_DIF, CFSTR("org.winehq.builtin.dif"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_ENHMETAFILE, CFSTR("org.winehq.builtin.enhmetafile"), import_enhmetafile, export_enhmetafile, FALSE }, { CF_LOCALE, CFSTR("org.winehq.builtin.locale"), import_clipboard_data, export_clipboard_data, FALSE }, @@ -161,15 +163,9 @@ static const struct { CF_TIFF, CFSTR("public.tiff"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_WAVE, CFSTR("com.microsoft.waveform-audio"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_BITMAP, CFSTR("org.winehq.builtin.bitmap"), import_bmp_to_bitmap, export_bitmap_to_bmp, FALSE }, - { CF_BITMAP, CFSTR("com.microsoft.bmp"), import_bmp_to_bitmap, export_bitmap_to_bmp, TRUE }, - { CF_DIB, CFSTR("org.winehq.builtin.dib"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_DIB, CFSTR("com.microsoft.bmp"), import_bmp_to_dib, export_dib_to_bmp, TRUE }, - { CF_DIBV5, CFSTR("org.winehq.builtin.dibv5"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_DIBV5, CFSTR("com.microsoft.bmp"), import_bmp_to_dib, export_dib_to_bmp, TRUE }, - { CF_HDROP, CFSTR("org.winehq.builtin.hdrop"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_HDROP, CFSTR("NSFilenamesPboardType"), import_nsfilenames_to_hdrop, export_hdrop_to_filenames, TRUE }, -- 2.8.2 From ken at codeweavers.com Sun Oct 23 13:03:25 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:25 -0500 Subject: [PATCH 06/15] winemac: Don't export/import CF_TEXT or CF_OEMTEXT to/from Mac-native data types. In-Reply-To: <1477245814-49846-1-git-send-email-ken@codeweavers.com> References: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Message-ID: <1477245814-49846-6-git-send-email-ken@codeweavers.com> The relevant Mac-native types, public.utf16-plain-text and public.utf8-plain-text, are handled by CF_UNICODETEXT and user32 handles the synthesis of CF_TEXT and CF_OEMTEXT from that. CF_TEXT and CF_OEMTEXT are still exported and imported with a Wine-specific type to preserve cross-prefix copy/paste fidelity. Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 281 +++++++++---------------------------------- 1 file changed, 58 insertions(+), 223 deletions(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index b0c1e49..15f0992 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -76,11 +76,8 @@ static HANDLE import_bmp_to_dib(CFDataRef data); static HANDLE import_enhmetafile(CFDataRef data); static HANDLE import_metafilepict(CFDataRef data); static HANDLE import_nsfilenames_to_hdrop(CFDataRef data); -static HANDLE import_utf8_to_oemtext(CFDataRef data); static HANDLE import_utf8_to_text(CFDataRef data); static HANDLE import_utf8_to_unicodetext(CFDataRef data); -static HANDLE import_utf16_to_oemtext(CFDataRef data); -static HANDLE import_utf16_to_text(CFDataRef data); static HANDLE import_utf16_to_unicodetext(CFDataRef data); static CFDataRef export_clipboard_data(HANDLE data); @@ -89,10 +86,7 @@ static CFDataRef export_dib_to_bmp(HANDLE data); static CFDataRef export_enhmetafile(HANDLE data); static CFDataRef export_hdrop_to_filenames(HANDLE data); static CFDataRef export_metafilepict(HANDLE data); -static CFDataRef export_oemtext_to_utf8(HANDLE data); -static CFDataRef export_oemtext_to_utf16(HANDLE data); static CFDataRef export_text_to_utf8(HANDLE data); -static CFDataRef export_text_to_utf16(HANDLE data); static CFDataRef export_unicodetext_to_utf8(HANDLE data); static CFDataRef export_unicodetext_to_utf16(HANDLE data); @@ -156,10 +150,12 @@ static const struct { CF_ENHMETAFILE, CFSTR("org.winehq.builtin.enhmetafile"), import_enhmetafile, export_enhmetafile, FALSE }, { CF_LOCALE, CFSTR("org.winehq.builtin.locale"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_METAFILEPICT, CFSTR("org.winehq.builtin.metafilepict"), import_metafilepict, export_metafilepict, FALSE }, + { CF_OEMTEXT, CFSTR("org.winehq.builtin.oemtext"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_PALETTE, CFSTR("org.winehq.builtin.palette"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_PENDATA, CFSTR("org.winehq.builtin.pendata"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_RIFF, CFSTR("org.winehq.builtin.riff"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_SYLK, CFSTR("org.winehq.builtin.sylk"), import_clipboard_data, export_clipboard_data, FALSE }, + { CF_TEXT, CFSTR("org.winehq.builtin.text"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_TIFF, CFSTR("public.tiff"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_WAVE, CFSTR("com.microsoft.waveform-audio"), import_clipboard_data, export_clipboard_data, FALSE }, @@ -169,14 +165,6 @@ static const struct { CF_HDROP, CFSTR("org.winehq.builtin.hdrop"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_HDROP, CFSTR("NSFilenamesPboardType"), import_nsfilenames_to_hdrop, export_hdrop_to_filenames, TRUE }, - { CF_OEMTEXT, CFSTR("org.winehq.builtin.oemtext"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_OEMTEXT, CFSTR("public.utf16-plain-text"), import_utf16_to_oemtext, export_oemtext_to_utf16, TRUE }, - { CF_OEMTEXT, CFSTR("public.utf8-plain-text"), import_utf8_to_oemtext, export_oemtext_to_utf8, TRUE }, - - { CF_TEXT, CFSTR("org.winehq.builtin.text"), import_clipboard_data, export_clipboard_data, FALSE }, - { CF_TEXT, CFSTR("public.utf16-plain-text"), import_utf16_to_text, export_text_to_utf16, TRUE }, - { CF_TEXT, CFSTR("public.utf8-plain-text"), import_utf8_to_text, export_text_to_utf8, TRUE }, - { CF_UNICODETEXT, CFSTR("org.winehq.builtin.unicodetext"), import_clipboard_data, export_clipboard_data, FALSE }, { CF_UNICODETEXT, CFSTR("public.utf16-plain-text"), import_utf16_to_unicodetext, export_unicodetext_to_utf16,TRUE }, { CF_UNICODETEXT, CFSTR("public.utf8-plain-text"), import_utf8_to_unicodetext, export_unicodetext_to_utf8, TRUE }, @@ -389,87 +377,6 @@ static WINE_CLIPFORMAT* natural_format_for_format(UINT format_id) } -/************************************************************************** - * convert_text - * - * Convert string data between code pages or to/from wide characters. The - * special value of (UINT)-1 for a code page indicates to use wide - * characters. - */ -static HANDLE convert_text(const void *src, int src_len, UINT src_cp, UINT dest_cp) -{ - HANDLE ret = NULL; - const WCHAR *wstr; - int wstr_len; - HANDLE handle; - char *p; - - if (src_cp == (UINT)-1) - { - wstr = src; - wstr_len = src_len / sizeof(WCHAR); - } - else - { - WCHAR *temp; - - wstr_len = MultiByteToWideChar(src_cp, 0, src, src_len, NULL, 0); - if (!src_len || ((const char*)src)[src_len - 1]) wstr_len += 1; - temp = HeapAlloc(GetProcessHeap(), 0, wstr_len * sizeof(WCHAR)); - MultiByteToWideChar(src_cp, 0, src, src_len, temp, wstr_len); - temp[wstr_len - 1] = 0; - wstr = temp; - } - - if (dest_cp == (UINT)-1) - { - handle = GlobalAlloc(GMEM_FIXED, wstr_len * sizeof(WCHAR)); - if (handle && (p = GlobalLock(handle))) - { - memcpy(p, wstr, wstr_len * sizeof(WCHAR)); - GlobalUnlock(handle); - ret = handle; - } - } - else - { - INT len; - - len = WideCharToMultiByte(dest_cp, 0, wstr, wstr_len, NULL, 0, NULL, NULL); - if (!wstr_len || wstr[wstr_len - 1]) len += 1; - handle = GlobalAlloc(GMEM_FIXED, len); - - if (handle && (p = GlobalLock(handle))) - { - WideCharToMultiByte(dest_cp, 0, wstr, wstr_len, p, len, NULL, NULL); - p[len - 1] = 0; - GlobalUnlock(handle); - ret = handle; - } - } - - return ret; -} - - -/************************************************************************** - * convert_unicodetext_to_codepage - */ -static HANDLE convert_unicodetext_to_codepage(HANDLE unicode_handle, UINT cp) -{ - LPWSTR unicode_string = GlobalLock(unicode_handle); - HANDLE ret = NULL; - - if (unicode_string) - { - ret = convert_text(unicode_string, GlobalSize(unicode_handle), -1, cp); - GlobalUnlock(unicode_handle); - } - - return ret; -} - - /*********************************************************************** * bitmap_info_size * @@ -858,29 +765,38 @@ done: /************************************************************************** - * import_utf8_to_oemtext - * - * Import a UTF-8 string, converting the string to CF_OEMTEXT. - */ -static HANDLE import_utf8_to_oemtext(CFDataRef data) -{ - HANDLE unicode_handle = import_utf8_to_unicodetext(data); - HANDLE ret = convert_unicodetext_to_codepage(unicode_handle, CP_OEMCP); - - GlobalFree(unicode_handle); - return ret; -} - - -/************************************************************************** * import_utf8_to_text * * Import a UTF-8 string, converting the string to CF_TEXT. */ static HANDLE import_utf8_to_text(CFDataRef data) { + HANDLE ret = NULL; HANDLE unicode_handle = import_utf8_to_unicodetext(data); - HANDLE ret = convert_unicodetext_to_codepage(unicode_handle, CP_ACP); + LPWSTR unicode_string = GlobalLock(unicode_handle); + + if (unicode_string) + { + int unicode_len; + HANDLE handle; + char *p; + INT len; + + unicode_len = GlobalSize(unicode_handle) / sizeof(WCHAR); + + len = WideCharToMultiByte(CP_ACP, 0, unicode_string, unicode_len, NULL, 0, NULL, NULL); + if (!unicode_len || unicode_string[unicode_len - 1]) len += 1; + handle = GlobalAlloc(GMEM_FIXED, len); + + if (handle && (p = GlobalLock(handle))) + { + WideCharToMultiByte(CP_ACP, 0, unicode_string, unicode_len, p, len, NULL, NULL); + p[len - 1] = 0; + GlobalUnlock(handle); + ret = handle; + } + GlobalUnlock(unicode_handle); + } GlobalFree(unicode_handle); return ret; @@ -940,36 +856,6 @@ static HANDLE import_utf8_to_unicodetext(CFDataRef data) /************************************************************************** - * import_utf16_to_oemtext - * - * Import a UTF-16 string, converting the string to CF_OEMTEXT. - */ -static HANDLE import_utf16_to_oemtext(CFDataRef data) -{ - HANDLE unicode_handle = import_utf16_to_unicodetext(data); - HANDLE ret = convert_unicodetext_to_codepage(unicode_handle, CP_OEMCP); - - GlobalFree(unicode_handle); - return ret; -} - - -/************************************************************************** - * import_utf16_to_text - * - * Import a UTF-16 string, converting the string to CF_TEXT. - */ -static HANDLE import_utf16_to_text(CFDataRef data) -{ - HANDLE unicode_handle = import_utf16_to_unicodetext(data); - HANDLE ret = convert_unicodetext_to_codepage(unicode_handle, CP_ACP); - - GlobalFree(unicode_handle); - return ret; -} - - -/************************************************************************** * import_utf16_to_unicodetext * * Import a UTF-8 string, converting the string to CF_UNICODETEXT. @@ -1060,54 +946,6 @@ static CFDataRef export_bitmap_to_bmp(HANDLE data) /************************************************************************** - * export_codepage_to_utf8 - * - * Export string data in a specified codepage to UTF-8. - */ -static CFDataRef export_codepage_to_utf8(HANDLE data, UINT cp) -{ - CFDataRef ret = NULL; - const char* str; - - if ((str = GlobalLock(data))) - { - HANDLE unicode = convert_text(str, GlobalSize(data), cp, -1); - - ret = export_unicodetext_to_utf8(unicode); - - GlobalFree(unicode); - GlobalUnlock(data); - } - - return ret; -} - - -/************************************************************************** - * export_codepage_to_utf16 - * - * Export string data in a specified codepage to UTF-16. - */ -static CFDataRef export_codepage_to_utf16(HANDLE data, UINT cp) -{ - CFDataRef ret = NULL; - const char* str; - - if ((str = GlobalLock(data))) - { - HANDLE unicode = convert_text(str, GlobalSize(data), cp, -1); - - ret = export_unicodetext_to_utf16(unicode); - - GlobalFree(unicode); - GlobalUnlock(data); - } - - return ret; -} - - -/************************************************************************** * export_dib_to_bmp * * Export CF_DIB or CF_DIBV5 to BMP file format. This just entails @@ -1290,46 +1128,43 @@ static CFDataRef export_metafilepict(HANDLE data) /************************************************************************** - * export_oemtext_to_utf8 - * - * Export CF_OEMTEXT to UTF-8. - */ -static CFDataRef export_oemtext_to_utf8(HANDLE data) -{ - return export_codepage_to_utf8(data, CP_OEMCP); -} - - -/************************************************************************** - * export_oemtext_to_utf16 - * - * Export CF_OEMTEXT to UTF-16. - */ -static CFDataRef export_oemtext_to_utf16(HANDLE data) -{ - return export_codepage_to_utf16(data, CP_OEMCP); -} - - -/************************************************************************** * export_text_to_utf8 * * Export CF_TEXT to UTF-8. */ static CFDataRef export_text_to_utf8(HANDLE data) { - return export_codepage_to_utf8(data, CP_ACP); -} - - -/************************************************************************** - * export_text_to_utf16 - * - * Export CF_TEXT to UTF-16. - */ -static CFDataRef export_text_to_utf16(HANDLE data) -{ - return export_codepage_to_utf16(data, CP_ACP); + CFDataRef ret = NULL; + const char* str; + + if ((str = GlobalLock(data))) + { + int str_len = GlobalSize(data); + int wstr_len; + WCHAR *wstr; + HANDLE unicode; + char *p; + + wstr_len = MultiByteToWideChar(CP_ACP, 0, str, str_len, NULL, 0); + if (!str_len || str[str_len - 1]) wstr_len += 1; + wstr = HeapAlloc(GetProcessHeap(), 0, wstr_len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, str, str_len, wstr, wstr_len); + wstr[wstr_len - 1] = 0; + + unicode = GlobalAlloc(GMEM_FIXED, wstr_len * sizeof(WCHAR)); + if (unicode && (p = GlobalLock(unicode))) + { + memcpy(p, wstr, wstr_len * sizeof(WCHAR)); + GlobalUnlock(unicode); + } + + ret = export_unicodetext_to_utf8(unicode); + + GlobalFree(unicode); + GlobalUnlock(data); + } + + return ret; } -- 2.8.2 From ken at codeweavers.com Sun Oct 23 13:03:26 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:26 -0500 Subject: [PATCH 07/15] winemac: Clamp the number of colors to <= 256 in bitmap_info_size(). In-Reply-To: <1477245814-49846-1-git-send-email-ken@codeweavers.com> References: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Message-ID: <1477245814-49846-7-git-send-email-ken@codeweavers.com> … as is done in user32's and gdi32's version of the same function. Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index 15f0992..4c66b9f 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -395,7 +395,7 @@ static int bitmap_info_size(const BITMAPINFO *info, WORD coloruse) } else /* assume BITMAPINFOHEADER */ { - colors = info->bmiHeader.biClrUsed; + colors = MIN(info->bmiHeader.biClrUsed, 256); if (!colors && (info->bmiHeader.biBitCount <= 8)) colors = 1 << info->bmiHeader.biBitCount; if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3; -- 2.8.2 From ken at codeweavers.com Sun Oct 23 13:03:27 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:27 -0500 Subject: [PATCH 08/15] winemac: Use GetDIBits to retrieve the bitmap header when exporting a bitmap. In-Reply-To: <1477245814-49846-1-git-send-email-ken@codeweavers.com> References: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Message-ID: <1477245814-49846-8-git-send-email-ken@codeweavers.com> Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 83 +++++++++----------------------------------- 1 file changed, 17 insertions(+), 66 deletions(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index 4c66b9f..75563ad 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -410,77 +410,28 @@ static int bitmap_info_size(const BITMAPINFO *info, WORD coloruse) * * Allocates a packed DIB and copies the bitmap data into it. */ -static HGLOBAL create_dib_from_bitmap(HBITMAP hBmp) +static HGLOBAL create_dib_from_bitmap(HBITMAP bitmap) { - BITMAP bmp; - HDC hdc; - HGLOBAL hPackedDIB; - LPBYTE pPackedDIB; - LPBITMAPINFOHEADER pbmiHeader; - unsigned int cDataSize, cPackedSize, OffsetBits; - int nLinesCopied; + HANDLE ret = 0; + BITMAPINFOHEADER header; + HDC hdc = GetDC(0); + DWORD header_size; + BITMAPINFO *bmi; - if (!GetObjectW(hBmp, sizeof(bmp), &bmp)) return 0; + memset(&header, 0, sizeof(header)); + header.biSize = sizeof(header); + if (!GetDIBits(hdc, bitmap, 0, 0, NULL, (BITMAPINFO *)&header, DIB_RGB_COLORS)) goto done; - /* - * A packed DIB contains a BITMAPINFO structure followed immediately by - * an optional color palette and the pixel data. - */ + header_size = bitmap_info_size((BITMAPINFO *)&header, DIB_RGB_COLORS); + if (!(ret = GlobalAlloc(GMEM_FIXED, header_size + header.biSizeImage))) goto done; + bmi = (BITMAPINFO *)ret; + memset(bmi, 0, header_size); + memcpy(bmi, &header, header.biSize); + GetDIBits(hdc, bitmap, 0, abs(header.biHeight), (char *)bmi + header_size, bmi, DIB_RGB_COLORS); - /* Calculate the size of the packed DIB */ - cDataSize = abs(bmp.bmHeight) * (((bmp.bmWidth * bmp.bmBitsPixel + 31) / 8) & ~3); - cPackedSize = sizeof(BITMAPINFOHEADER) - + ((bmp.bmBitsPixel <= 8) ? (sizeof(RGBQUAD) * (1 << bmp.bmBitsPixel)) : 0) - + cDataSize; - /* Get the offset to the bits */ - OffsetBits = cPackedSize - cDataSize; - - /* Allocate the packed DIB */ - TRACE("\tAllocating packed DIB of size %d\n", cPackedSize); - hPackedDIB = GlobalAlloc(GMEM_FIXED, cPackedSize); - if (!hPackedDIB) - { - WARN("Could not allocate packed DIB!\n"); - return 0; - } - - /* A packed DIB starts with a BITMAPINFOHEADER */ - pPackedDIB = GlobalLock(hPackedDIB); - pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB; - - /* Init the BITMAPINFOHEADER */ - pbmiHeader->biSize = sizeof(BITMAPINFOHEADER); - pbmiHeader->biWidth = bmp.bmWidth; - pbmiHeader->biHeight = bmp.bmHeight; - pbmiHeader->biPlanes = 1; - pbmiHeader->biBitCount = bmp.bmBitsPixel; - pbmiHeader->biCompression = BI_RGB; - pbmiHeader->biSizeImage = 0; - pbmiHeader->biXPelsPerMeter = pbmiHeader->biYPelsPerMeter = 0; - pbmiHeader->biClrUsed = 0; - pbmiHeader->biClrImportant = 0; - - /* Retrieve the DIB bits from the bitmap and fill in the - * DIB color table if present */ - hdc = GetDC(0); - nLinesCopied = GetDIBits(hdc, /* Handle to device context */ - hBmp, /* Handle to bitmap */ - 0, /* First scan line to set in dest bitmap */ - bmp.bmHeight, /* Number of scan lines to copy */ - pPackedDIB + OffsetBits, /* [out] Address of array for bitmap bits */ - (LPBITMAPINFO) pbmiHeader, /* [out] Address of BITMAPINFO structure */ - 0); /* RGB or palette index */ - GlobalUnlock(hPackedDIB); +done: ReleaseDC(0, hdc); - - /* Cleanup if GetDIBits failed */ - if (nLinesCopied != bmp.bmHeight) - { - TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied, bmp.bmHeight); - GlobalFree(hPackedDIB); - hPackedDIB = 0; - } - return hPackedDIB; + return ret; } -- 2.8.2 From ken at codeweavers.com Sun Oct 23 13:03:28 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:28 -0500 Subject: [PATCH 09/15] winemac: Remove no-longer-called clipboard entry points. In-Reply-To: <1477245814-49846-1-git-send-email-ken@codeweavers.com> References: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Message-ID: <1477245814-49846-9-git-send-email-ken@codeweavers.com> Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 294 -------------------------------------- dlls/winemac.drv/winemac.drv.spec | 7 - 2 files changed, 301 deletions(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index 75563ad..f974bf2 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -1232,28 +1232,6 @@ static BOOL get_clipboard_info(LPCLIPBOARDINFO cbinfo) /************************************************************************** - * release_ownership - */ -static BOOL release_ownership(void) -{ - BOOL ret = FALSE; - - SERVER_START_REQ(set_clipboard_info) - { - req->flags = SET_CB_RELOWNER | SET_CB_SEQNO; - - if (wine_server_call_err(req)) - ERR("Failed to set clipboard.\n"); - else - ret = TRUE; - } - SERVER_END_REQ; - - return ret; -} - - -/************************************************************************** * macdrv_get_pasteboard_data */ HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format) @@ -1490,283 +1468,11 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) /************************************************************************** - * check_clipboard_ownership - */ -static void check_clipboard_ownership(HWND *owner) -{ - CLIPBOARDINFO cbinfo; - - if (owner) *owner = NULL; - - /* If Wine thinks we're the clipboard owner but Mac OS X thinks we're not - the pasteboard owner, update Wine. */ - if (get_clipboard_info(&cbinfo) && (cbinfo.flags & CB_PROCESS)) - { - if (!(cbinfo.flags & CB_OPEN) && !macdrv_is_pasteboard_owner()) - { - TRACE("Lost clipboard ownership\n"); - - if (OpenClipboard(cbinfo.hwnd_owner)) - { - /* Destroy private objects */ - SendMessageW(cbinfo.hwnd_owner, WM_DESTROYCLIPBOARD, 0, 0); - - /* Give up ownership of the windows clipboard */ - release_ownership(); - CloseClipboard(); - } - } - else if (owner) - *owner = cbinfo.hwnd_owner; - } -} - - -/************************************************************************** * Mac User Driver Clipboard Exports **************************************************************************/ /************************************************************************** - * CountClipboardFormats (MACDRV.@) - */ -INT CDECL macdrv_CountClipboardFormats(void) -{ - CFMutableSetRef seen_formats; - CFArrayRef types; - CFIndex count; - CFIndex i; - INT ret = 0; - - TRACE("()\n"); - check_clipboard_ownership(NULL); - - seen_formats = CFSetCreateMutable(NULL, 0, NULL); - if (!seen_formats) - { - WARN("Failed to allocate set to track seen formats\n"); - return 0; - } - - types = macdrv_copy_pasteboard_types(NULL); - if (!types) - { - WARN("Failed to copy pasteboard types\n"); - CFRelease(seen_formats); - return 0; - } - - count = CFArrayGetCount(types); - TRACE("got %ld types\n", count); - - for (i = 0; i < count; i++) - { - CFStringRef type = CFArrayGetValueAtIndex(types, i); - WINE_CLIPFORMAT* format; - - format = NULL; - while ((format = format_for_type(format, type))) - { - TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); - - if (!CFSetContainsValue(seen_formats, (void*)format->format_id)) - { - ret++; - CFSetAddValue(seen_formats, (void*)format->format_id); - } - } - } - - CFRelease(types); - CFRelease(seen_formats); - TRACE(" -> %d\n", ret); - return ret; -} - - -/************************************************************************** - * EmptyClipboard (MACDRV.@) - * - * Empty cached clipboard data. - */ -void CDECL macdrv_EmptyClipboard(void) -{ - TRACE("()\n"); - check_clipboard_ownership(NULL); - macdrv_clear_pasteboard(); -} - - -/************************************************************************** - * EndClipboardUpdate (MACDRV.@) - */ -void CDECL macdrv_EndClipboardUpdate(void) -{ - TRACE("()\n"); - check_clipboard_ownership(NULL); -} - - -/************************************************************************** - * EnumClipboardFormats (MACDRV.@) - */ -UINT CDECL macdrv_EnumClipboardFormats(UINT prev_format) -{ - CFArrayRef formats; - CFIndex count; - CFIndex i; - UINT ret = 0; - - TRACE("prev_format %s\n", debugstr_format(prev_format)); - check_clipboard_ownership(NULL); - - formats = macdrv_copy_pasteboard_formats(NULL); - if (formats) - { - count = CFArrayGetCount(formats); - if (prev_format) - { - i = CFArrayGetFirstIndexOfValue(formats, CFRangeMake(0, count), (void*)prev_format); - if (i != kCFNotFound) - i++; - } - else - i = 0; - - if (i != kCFNotFound && i < count) - ret = (UINT)CFArrayGetValueAtIndex(formats, i); - - CFRelease(formats); - } - - TRACE(" -> %u\n", ret); - return ret; -} - - -/************************************************************************** - * GetClipboardData (MACDRV.@) - */ -HANDLE CDECL macdrv_GetClipboardData(UINT desired_format) -{ - check_clipboard_ownership(NULL); - - return macdrv_get_pasteboard_data(NULL, desired_format); -} - - -/************************************************************************** - * IsClipboardFormatAvailable (MACDRV.@) - */ -BOOL CDECL macdrv_IsClipboardFormatAvailable(UINT desired_format) -{ - check_clipboard_ownership(NULL); - return macdrv_pasteboard_has_format(NULL, desired_format); -} - - -/************************************************************************** - * SetClipboardData (MACDRV.@) - */ -BOOL CDECL macdrv_SetClipboardData(UINT format_id, HANDLE data, BOOL owner) -{ - HWND hwnd_owner; - macdrv_window window; - WINE_CLIPFORMAT *format; - CFDataRef cfdata = NULL; - - check_clipboard_ownership(&hwnd_owner); - window = macdrv_get_cocoa_window(GetAncestor(hwnd_owner, GA_ROOT), FALSE); - TRACE("format_id %s data %p owner %d hwnd_owner %p window %p)\n", debugstr_format(format_id), data, owner, hwnd_owner, window); - - format = natural_format_for_format(format_id); - if (!format && !(format = insert_clipboard_format(format_id, NULL))) - { - WARN("Failed to register clipboard format %s\n", debugstr_format(format_id)); - return FALSE; - } - - /* Export the data to the Mac pasteboard. */ - if (data) - { - if (!format->export_func || !(cfdata = format->export_func(data))) - { - WARN("Failed to export %s data to type %s\n", debugstr_format(format_id), debugstr_cf(format->type)); - return FALSE; - } - } - - if (macdrv_set_pasteboard_data(format->type, cfdata, window)) - TRACE("Set pasteboard data for type %s: %s\n", debugstr_cf(format->type), debugstr_cf(cfdata)); - else - { - WARN("Failed to set pasteboard data for type %s: %s\n", debugstr_cf(format->type), debugstr_cf(cfdata)); - if (cfdata) CFRelease(cfdata); - return FALSE; - } - - if (cfdata) CFRelease(cfdata); - - /* Find any other formats for this format_id (the exportable synthesized ones). */ - LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry) - { - if (format->format_id == format_id && format->synthesized && format->export_func) - { - /* We have a synthesized format for this format ID. Add its type to the pasteboard. */ - TRACE("Synthesized from format %s: type %s\n", debugstr_format(format_id), debugstr_cf(format->type)); - - if (data) - { - cfdata = format->export_func(data); - if (!cfdata) - { - WARN("Failed to export %s data to type %s\n", debugstr_format(format->format_id), debugstr_cf(format->type)); - continue; - } - } - else - cfdata = NULL; - - if (macdrv_set_pasteboard_data(format->type, cfdata, window)) - TRACE(" ... set pasteboard data: %s\n", debugstr_cf(cfdata)); - else - WARN(" ... failed to set pasteboard data: %s\n", debugstr_cf(cfdata)); - - if (cfdata) CFRelease(cfdata); - } - } - - if (data) - { - /* FIXME: According to MSDN, the caller is entitled to lock and read from - data until CloseClipboard is called. So, we should defer this cleanup. */ - if ((format_id >= CF_GDIOBJFIRST && format_id <= CF_GDIOBJLAST) || - format_id == CF_BITMAP || - format_id == CF_DIB || - format_id == CF_PALETTE) - { - DeleteObject(data); - } - else if (format_id == CF_METAFILEPICT) - { - DeleteMetaFile(((METAFILEPICT *)GlobalLock(data))->hMF); - GlobalFree(data); - } - else if (format_id == CF_ENHMETAFILE) - { - DeleteEnhMetaFile(data); - } - else if (format_id < CF_PRIVATEFIRST || CF_PRIVATELAST < format_id) - { - GlobalFree(data); - } - } - - return TRUE; -} - - -/************************************************************************** * MACDRV Private Clipboard Exports **************************************************************************/ diff --git a/dlls/winemac.drv/winemac.drv.spec b/dlls/winemac.drv/winemac.drv.spec index 2e29722..3e6619e 100644 --- a/dlls/winemac.drv/winemac.drv.spec +++ b/dlls/winemac.drv/winemac.drv.spec @@ -8,29 +8,22 @@ @ cdecl Beep() macdrv_Beep @ cdecl ChangeDisplaySettingsEx(ptr ptr long long long) macdrv_ChangeDisplaySettingsEx @ cdecl ClipCursor(ptr) macdrv_ClipCursor -@ cdecl CountClipboardFormats() macdrv_CountClipboardFormats @ cdecl CreateDesktopWindow(long) macdrv_CreateDesktopWindow @ cdecl CreateWindow(long) macdrv_CreateWindow @ cdecl DestroyCursorIcon(long) macdrv_DestroyCursorIcon @ cdecl DestroyWindow(long) macdrv_DestroyWindow -@ cdecl EmptyClipboard() macdrv_EmptyClipboard -@ cdecl EndClipboardUpdate() macdrv_EndClipboardUpdate -@ cdecl EnumClipboardFormats(long) macdrv_EnumClipboardFormats @ cdecl EnumDisplayMonitors(long ptr ptr long) macdrv_EnumDisplayMonitors @ cdecl EnumDisplaySettingsEx(ptr long ptr long) macdrv_EnumDisplaySettingsEx -@ cdecl GetClipboardData(long) macdrv_GetClipboardData @ cdecl GetCursorPos(ptr) macdrv_GetCursorPos @ cdecl GetKeyboardLayout(long) macdrv_GetKeyboardLayout @ cdecl GetKeyboardLayoutList(long ptr) macdrv_GetKeyboardLayoutList @ cdecl GetKeyboardLayoutName(ptr) macdrv_GetKeyboardLayoutName @ cdecl GetKeyNameText(long ptr long) macdrv_GetKeyNameText @ cdecl GetMonitorInfo(long ptr) macdrv_GetMonitorInfo -@ cdecl IsClipboardFormatAvailable(long) macdrv_IsClipboardFormatAvailable @ cdecl MapVirtualKeyEx(long long long) macdrv_MapVirtualKeyEx @ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) macdrv_MsgWaitForMultipleObjectsEx @ cdecl RegisterHotKey(long long long) macdrv_RegisterHotKey @ cdecl SetCapture(long long) macdrv_SetCapture -@ cdecl SetClipboardData(long long long) macdrv_SetClipboardData @ cdecl SetCursor(long) macdrv_SetCursor @ cdecl SetCursorPos(long long) macdrv_SetCursorPos @ cdecl SetFocus(long) macdrv_SetFocus -- 2.8.2 From ken at codeweavers.com Sun Oct 23 13:03:29 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:29 -0500 Subject: [PATCH 10/15] winemac: Simplify format_for_type() and callers since there's at most one format for a given Mac pasteboard type. In-Reply-To: <1477245814-49846-1-git-send-email-ken@codeweavers.com> References: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Message-ID: <1477245814-49846-10-git-send-email-ken@codeweavers.com> Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 216 +++++++++++++++++-------------------------- 1 file changed, 83 insertions(+), 133 deletions(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index f974bf2..414ad6a 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -310,44 +310,39 @@ static WINE_CLIPFORMAT* register_format(UINT id, CFStringRef type) /************************************************************************** * format_for_type */ -static WINE_CLIPFORMAT* format_for_type(WINE_CLIPFORMAT *current, CFStringRef type) +static WINE_CLIPFORMAT* format_for_type(CFStringRef type) { - struct list *ptr = current ? ¤t->entry : &format_list; - WINE_CLIPFORMAT *format = NULL; + WINE_CLIPFORMAT *format; - TRACE("current %p/%s type %s\n", current, debugstr_format(current ? current->format_id : 0), debugstr_cf(type)); + TRACE("type %s\n", debugstr_cf(type)); - while ((ptr = list_next(&format_list, ptr))) + LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry) { - format = LIST_ENTRY(ptr, WINE_CLIPFORMAT, entry); if (CFEqual(format->type, type)) goto done; } format = NULL; - if (!current) + if (CFStringHasPrefix(type, CFSTR("org.winehq.builtin."))) { - if (CFStringHasPrefix(type, CFSTR("org.winehq.builtin."))) - { - ERR("Shouldn't happen. Built-in type %s should have matched something in format list.\n", - debugstr_cf(type)); - } - else if (CFStringHasPrefix(type, registered_name_type_prefix)) - { - LPWSTR name; - int len = CFStringGetLength(type) - CFStringGetLength(registered_name_type_prefix); + ERR("Shouldn't happen. Built-in type %s should have matched something in format list.\n", + debugstr_cf(type)); + } + else if (CFStringHasPrefix(type, registered_name_type_prefix)) + { + LPWSTR name; + int len = CFStringGetLength(type) - CFStringGetLength(registered_name_type_prefix); - name = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); - CFStringGetCharacters(type, CFRangeMake(CFStringGetLength(registered_name_type_prefix), len), - (UniChar*)name); - name[len] = 0; + name = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); + CFStringGetCharacters(type, CFRangeMake(CFStringGetLength(registered_name_type_prefix), len), + (UniChar*)name); + name[len] = 0; - format = register_format(RegisterClipboardFormatW(name), type); - if (!format) - ERR("Failed to register format for type %s name %s\n", debugstr_cf(type), debugstr_w(name)); + format = register_format(RegisterClipboardFormatW(name), type); + if (!format) + ERR("Failed to register format for type %s name %s\n", debugstr_cf(type), debugstr_w(name)); - HeapFree(GetProcessHeap(), 0, name); - } + HeapFree(GetProcessHeap(), 0, name); } done: @@ -1261,10 +1256,9 @@ HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format) type = CFArrayGetValueAtIndex(types, i); - format = NULL; - while ((!best_format || best_format->synthesized) && (format = format_for_type(format, type))) + if ((format = format_for_type(type))) { - TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format ? format->format_id : 0)); + TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); if (format->format_id == desired_format) { @@ -1320,18 +1314,20 @@ BOOL macdrv_pasteboard_has_format(CFTypeRef pasteboard, UINT desired_format) count = CFArrayGetCount(types); TRACE("got %d types\n", count); - for (i = 0; !found && i < count; i++) + for (i = 0; i < count; i++) { CFStringRef type = CFArrayGetValueAtIndex(types, i); - WINE_CLIPFORMAT* format; + WINE_CLIPFORMAT* format = format_for_type(type); - format = NULL; - while (!found && (format = format_for_type(format, type))) + if (format) { TRACE("for type %s got format %s\n", debugstr_cf(type), debugstr_format(format->format_id)); if (format->format_id == desired_format) + { found = TRUE; + break; + } } } @@ -1381,62 +1377,34 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) for (i = 0; i < count; i++) { CFStringRef type = CFArrayGetValueAtIndex(types, i); - BOOL found = FALSE; - format = NULL; - while ((format = format_for_type(format, type))) + format = format_for_type(type); + if (!format) { - /* Suppose type is "public.utf8-plain-text". format->format_id will be each of - CF_TEXT, CF_OEMTEXT, and CF_UNICODETEXT in turn. We want to look up the natural - type for each of those IDs (e.g. CF_TEXT -> "org.winehq.builtin.text") and then see - if that type is present in the pasteboard. If it is, then we don't want to add the - format to the list yet because it would be out of order. - - For example, if a Mac app put "public.utf8-plain-text" and "public.tiff" on the - pasteboard, then we want the Win32 clipboard formats to be CF_TEXT, CF_OEMTEXT, and - CF_UNICODETEXT, and CF_TIFF, in that order. All of the text formats belong before - CF_TIFF because the Mac app expressed that text was "better" than the TIFF. In - this case, as soon as we encounter "public.utf8-plain-text" we should add all of - the associated text format IDs. - - But if a Wine process put "org.winehq.builtin.unicodetext", - "public.utf8-plain-text", "public.utf16-plain-text", and "public.tiff", then we - want the clipboard formats to be CF_UNICODETEXT, CF_TIFF, CF_TEXT, and CF_OEMTEXT, - in that order. The Windows program presumably added CF_UNICODETEXT and CF_TIFF. - We're synthesizing CF_TEXT and CF_OEMTEXT from CF_UNICODETEXT but we want them to - come after the non-synthesized CF_TIFF. In this case, we don't want to add the - text formats upon encountering "public.utf8-plain-text", - - We tell the two cases apart by seeing that one of the natural types for the text - formats (i.e. "org.winehq.builtin.unicodetext") is present on the pasteboard. - "found" indicates that. */ - - if (!format->synthesized) - { - TRACE("for type %s got primary format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); - CFArrayAppendValue(formats, (void*)format->format_id); - found = TRUE; - } - else if (!found && format->natural_format && - CFArrayContainsValue(types, CFRangeMake(0, count), format->natural_format->type)) - { - TRACE("for type %s deferring synthesized formats because type %s is also present\n", - debugstr_cf(type), debugstr_cf(format->natural_format->type)); - found = TRUE; - } + TRACE("ignoring type %s\n", debugstr_cf(type)); + continue; } - if (!found) + if (!format->synthesized) + { + TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); + CFArrayAppendValue(formats, (void*)format->format_id); + } + else if (format->natural_format && + CFArrayContainsValue(types, CFRangeMake(0, count), format->natural_format->type)) + { + TRACE("for type %s deferring synthesized formats because type %s is also present\n", + debugstr_cf(type), debugstr_cf(format->natural_format->type)); + } + else if (CFArrayContainsValue(formats, CFRangeMake(0, CFArrayGetCount(formats)), (void*)format->format_id)) + { + TRACE("for type %s got duplicate synthesized format %p/%s; skipping\n", debugstr_cf(type), format, + debugstr_format(format->format_id)); + } + else { - while ((format = format_for_type(format, type))) - { - /* Don't override a real value with a synthesized value. */ - if (!CFArrayContainsValue(formats, CFRangeMake(0, CFArrayGetCount(formats)), (void*)format->format_id)) - { - TRACE("for type %s got synthesized format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); - CFArrayAppendValue(formats, (void*)format->format_id); - } - } + TRACE("for type %s got synthesized format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); + CFArrayAppendValue(formats, (void*)format->format_id); } } @@ -1445,19 +1413,15 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) { CFStringRef type = CFArrayGetValueAtIndex(types, i); - format = NULL; - while ((format = format_for_type(format, type))) - { - if (format->synthesized) - { - /* Don't override a real value with a synthesized value. */ - if (!CFArrayContainsValue(formats, CFRangeMake(0, CFArrayGetCount(formats)), (void*)format->format_id)) - { - TRACE("for type %s got synthesized format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); - CFArrayAppendValue(formats, (void*)format->format_id); - } - } - } + format = format_for_type(type); + if (!format) continue; + if (!format->synthesized) continue; + + /* Don't duplicate a real value with a synthesized value. */ + if (CFArrayContainsValue(formats, CFRangeMake(0, CFArrayGetCount(formats)), (void*)format->format_id)) continue; + + TRACE("for type %s got synthesized format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); + CFArrayAppendValue(formats, (void*)format->format_id); } CFRelease(types); @@ -1528,53 +1492,39 @@ BOOL query_pasteboard_data(HWND hwnd, CFStringRef type) CLIPBOARDINFO cbinfo; WINE_CLIPFORMAT* format; CFArrayRef types = NULL; - CFRange range; TRACE("hwnd %p type %s\n", hwnd, debugstr_cf(type)); if (get_clipboard_info(&cbinfo)) hwnd = cbinfo.hwnd_owner; - format = NULL; - while ((format = format_for_type(format, type))) - { - TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); + format = format_for_type(type); + if (!format) goto done; - if (!format->synthesized) - { - TRACE("Sending WM_RENDERFORMAT message for format %s to hwnd %p\n", debugstr_format(format->format_id), hwnd); - SendMessageW(hwnd, WM_RENDERFORMAT, format->format_id, 0); - ret = TRUE; - goto done; - } + TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); - if (!types) - { - types = macdrv_copy_pasteboard_types(NULL); - if (!types) - { - WARN("Failed to copy pasteboard types\n"); - break; - } + if (!format->synthesized) + { + TRACE("Sending WM_RENDERFORMAT message for format %s to hwnd %p\n", debugstr_format(format->format_id), hwnd); + SendMessageW(hwnd, WM_RENDERFORMAT, format->format_id, 0); + ret = TRUE; + goto done; + } - range = CFRangeMake(0, CFArrayGetCount(types)); - } + types = macdrv_copy_pasteboard_types(NULL); + if (!types) + { + WARN("Failed to copy pasteboard types\n"); + goto done; + } - /* The type maps to a synthesized format. Now look up what type that format maps to natively - (not synthesized). For example, if type is "public.utf8-plain-text", then this format may - have an ID of CF_TEXT. From CF_TEXT, we want to find "org.winehq.builtin.text" to see if - that type is present in the pasteboard. If it is, then the app must have promised it and - we can ask it to render it. (If it had put it on the clipboard immediately, then the - pasteboard would also have data for "public.utf8-plain-text" and we wouldn't be here.) If - "org.winehq.builtin.text" is not on the pasteboard, then one of the other text formats is - presumably responsible for the promise that we're trying to satisfy, so we keep looking. */ - if (format->natural_format && CFArrayContainsValue(types, range, format->natural_format->type)) - { - TRACE("Sending WM_RENDERFORMAT message for format %s to hwnd %p\n", debugstr_format(format->format_id), hwnd); - SendMessageW(hwnd, WM_RENDERFORMAT, format->format_id, 0); - ret = TRUE; - goto done; - } + if (format->natural_format && + CFArrayContainsValue(types, CFRangeMake(0, CFArrayGetCount(types)), format->natural_format->type)) + { + TRACE("Sending WM_RENDERFORMAT message for format %s to hwnd %p\n", debugstr_format(format->format_id), hwnd); + SendMessageW(hwnd, WM_RENDERFORMAT, format->format_id, 0); + ret = TRUE; + goto done; } done: -- 2.8.2 From ken at codeweavers.com Sun Oct 23 13:03:30 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:30 -0500 Subject: [PATCH 11/15] winemac: Reimplement query_pasteboard_data() using the user32 clipboard API. In-Reply-To: <1477245814-49846-1-git-send-email-ken@codeweavers.com> References: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Message-ID: <1477245814-49846-11-git-send-email-ken@codeweavers.com> Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 81 ++++++++++---------------------------------- 1 file changed, 17 insertions(+), 64 deletions(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index 414ad6a..c196e93 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -40,12 +40,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(clipboard); * Types **************************************************************************/ -typedef struct -{ - HWND hwnd_owner; - UINT flags; -} CLIPBOARDINFO, *LPCLIPBOARDINFO; - typedef HANDLE (*DRVIMPORTFUNC)(CFDataRef data); typedef CFDataRef (*DRVEXPORTFUNC)(HANDLE data); @@ -1198,35 +1192,6 @@ static CFDataRef export_unicodetext_to_utf16(HANDLE data) /************************************************************************** - * get_clipboard_info - */ -static BOOL get_clipboard_info(LPCLIPBOARDINFO cbinfo) -{ - BOOL ret = FALSE; - - SERVER_START_REQ(set_clipboard_info) - { - req->flags = 0; - - if (wine_server_call_err(req)) - { - ERR("Failed to get clipboard owner.\n"); - } - else - { - cbinfo->hwnd_owner = wine_server_ptr_handle(reply->old_owner); - cbinfo->flags = reply->flags; - - ret = TRUE; - } - } - SERVER_END_REQ; - - return ret; -} - - -/************************************************************************** * macdrv_get_pasteboard_data */ HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format) @@ -1488,47 +1453,35 @@ void macdrv_clipboard_process_attach(void) */ BOOL query_pasteboard_data(HWND hwnd, CFStringRef type) { + WINE_CLIPFORMAT *format; BOOL ret = FALSE; - CLIPBOARDINFO cbinfo; - WINE_CLIPFORMAT* format; - CFArrayRef types = NULL; + HANDLE handle; - TRACE("hwnd %p type %s\n", hwnd, debugstr_cf(type)); - - if (get_clipboard_info(&cbinfo)) - hwnd = cbinfo.hwnd_owner; + TRACE("win %p type %s\n", hwnd, debugstr_cf(type)); format = format_for_type(type); - if (!format) goto done; + if (!format) return FALSE; - TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); - - if (!format->synthesized) + if (!OpenClipboard(NULL)) { - TRACE("Sending WM_RENDERFORMAT message for format %s to hwnd %p\n", debugstr_format(format->format_id), hwnd); - SendMessageW(hwnd, WM_RENDERFORMAT, format->format_id, 0); - ret = TRUE; - goto done; + ERR("failed to open clipboard for %s\n", debugstr_cf(type)); + return FALSE; } - types = macdrv_copy_pasteboard_types(NULL); - if (!types) + if ((handle = GetClipboardData(format->format_id))) { - WARN("Failed to copy pasteboard types\n"); - goto done; - } + CFDataRef data; - if (format->natural_format && - CFArrayContainsValue(types, CFRangeMake(0, CFArrayGetCount(types)), format->natural_format->type)) - { - TRACE("Sending WM_RENDERFORMAT message for format %s to hwnd %p\n", debugstr_format(format->format_id), hwnd); - SendMessageW(hwnd, WM_RENDERFORMAT, format->format_id, 0); - ret = TRUE; - goto done; + TRACE("exporting %s %p\n", debugstr_format(format->format_id), handle); + + if ((data = format->export_func(handle))) + { + ret = macdrv_set_pasteboard_data(format->type, data, macdrv_get_cocoa_window(hwnd, FALSE)); + CFRelease(data); + } } -done: - if (types) CFRelease(types); + CloseClipboard(); return ret; } -- 2.8.2 From ken at codeweavers.com Sun Oct 23 13:03:31 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:31 -0500 Subject: [PATCH 12/15] winemac: Change macdrv_copy_pasteboard_formats() to return a C array instead of a CFArray. In-Reply-To: <1477245814-49846-1-git-send-email-ken@codeweavers.com> References: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Message-ID: <1477245814-49846-12-git-send-email-ken@codeweavers.com> Renamed it to macdrv_get_pasteboard_formats(), since the "copy" was meant to convey Core Foundation ownership semantics which no longer apply. Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 83 +++++++++++++++++++++++++++++++++++--------- dlls/winemac.drv/dragdrop.c | 9 +++-- dlls/winemac.drv/macdrv.h | 2 +- 3 files changed, 72 insertions(+), 22 deletions(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index c196e93..eba426a 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -1303,17 +1303,17 @@ BOOL macdrv_pasteboard_has_format(CFTypeRef pasteboard, UINT desired_format) /************************************************************************** - * macdrv_copy_pasteboard_formats + * get_formats_for_pasteboard */ -CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) +static WINE_CLIPFORMAT** get_formats_for_pasteboard(CFTypeRef pasteboard, UINT *num_formats) { CFArrayRef types; - CFIndex count; - CFMutableArrayRef formats; - CFIndex i; - WINE_CLIPFORMAT* format; + CFIndex count, i; + CFMutableSetRef seen_formats; + WINE_CLIPFORMAT** formats; + UINT pos; - TRACE("pasteboard %p\n", pasteboard); + TRACE("pasteboard %s\n", debugstr_cf(pasteboard)); types = macdrv_copy_pasteboard_types(pasteboard); if (!types) @@ -1331,19 +1331,29 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) return NULL; } - formats = CFArrayCreateMutable(NULL, 0, NULL); + seen_formats = CFSetCreateMutable(NULL, count, NULL); + if (!seen_formats) + { + WARN("Failed to allocate seen formats set\n"); + CFRelease(types); + return NULL; + } + + formats = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*formats)); if (!formats) { WARN("Failed to allocate formats array\n"); CFRelease(types); + CFRelease(seen_formats); return NULL; } + pos = 0; for (i = 0; i < count; i++) { CFStringRef type = CFArrayGetValueAtIndex(types, i); + WINE_CLIPFORMAT* format = format_for_type(type); - format = format_for_type(type); if (!format) { TRACE("ignoring type %s\n", debugstr_cf(type)); @@ -1353,7 +1363,8 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) if (!format->synthesized) { TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); - CFArrayAppendValue(formats, (void*)format->format_id); + CFSetAddValue(seen_formats, (void*)format->format_id); + formats[pos++] = format; } else if (format->natural_format && CFArrayContainsValue(types, CFRangeMake(0, count), format->natural_format->type)) @@ -1361,7 +1372,7 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) TRACE("for type %s deferring synthesized formats because type %s is also present\n", debugstr_cf(type), debugstr_cf(format->natural_format->type)); } - else if (CFArrayContainsValue(formats, CFRangeMake(0, CFArrayGetCount(formats)), (void*)format->format_id)) + else if (CFSetContainsValue(seen_formats, (void*)format->format_id)) { TRACE("for type %s got duplicate synthesized format %p/%s; skipping\n", debugstr_cf(type), format, debugstr_format(format->format_id)); @@ -1369,7 +1380,8 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) else { TRACE("for type %s got synthesized format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); - CFArrayAppendValue(formats, (void*)format->format_id); + CFSetAddValue(seen_formats, (void*)format->format_id); + formats[pos++] = format; } } @@ -1377,26 +1389,65 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) for (i = 0; i < count; i++) { CFStringRef type = CFArrayGetValueAtIndex(types, i); + WINE_CLIPFORMAT* format = format_for_type(type); - format = format_for_type(type); if (!format) continue; if (!format->synthesized) continue; /* Don't duplicate a real value with a synthesized value. */ - if (CFArrayContainsValue(formats, CFRangeMake(0, CFArrayGetCount(formats)), (void*)format->format_id)) continue; + if (CFSetContainsValue(seen_formats, (void*)format->format_id)) continue; TRACE("for type %s got synthesized format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); - CFArrayAppendValue(formats, (void*)format->format_id); + CFSetAddValue(seen_formats, (void*)format->format_id); + formats[pos++] = format; } CFRelease(types); + CFRelease(seen_formats); - TRACE(" -> %s\n", debugstr_cf(formats)); + if (!pos) + { + HeapFree(GetProcessHeap(), 0, formats); + formats = NULL; + } + + *num_formats = pos; return formats; } /************************************************************************** + * macdrv_get_pasteboard_formats + */ +UINT* macdrv_get_pasteboard_formats(CFTypeRef pasteboard, UINT* num_formats) +{ + WINE_CLIPFORMAT** formats; + UINT count, i; + UINT* format_ids; + + formats = get_formats_for_pasteboard(pasteboard, &count); + if (!formats) + return NULL; + + format_ids = HeapAlloc(GetProcessHeap(), 0, count); + if (!format_ids) + { + WARN("Failed to allocate formats IDs array\n"); + HeapFree(GetProcessHeap(), 0, formats); + return NULL; + } + + for (i = 0; i < count; i++) + format_ids[i] = formats[i]->format_id; + + HeapFree(GetProcessHeap(), 0, formats); + + *num_formats = count; + return format_ids; +} + + +/************************************************************************** * Mac User Driver Clipboard Exports **************************************************************************/ diff --git a/dlls/winemac.drv/dragdrop.c b/dlls/winemac.drv/dragdrop.c index ad0bc8c..e089018 100644 --- a/dlls/winemac.drv/dragdrop.c +++ b/dlls/winemac.drv/dragdrop.c @@ -185,7 +185,7 @@ static HRESULT WINAPI dddo_EnumFormatEtc(IDataObject* iface, DWORD direction, IEnumFORMATETC** enumFormatEtc) { DragDropDataObject *This = impl_from_IDataObject(iface); - CFArrayRef formats; + UINT *formats, count; HRESULT hr; TRACE("This %p direction %u enumFormatEtc %p\n", This, direction, enumFormatEtc); @@ -196,10 +196,9 @@ static HRESULT WINAPI dddo_EnumFormatEtc(IDataObject* iface, DWORD direction, return E_NOTIMPL; } - formats = macdrv_copy_pasteboard_formats(This->pasteboard); + formats = macdrv_get_pasteboard_formats(This->pasteboard, &count); if (formats) { - INT count = CFArrayGetCount(formats); FORMATETC *formatEtcs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(FORMATETC)); if (formatEtcs) { @@ -207,7 +206,7 @@ static HRESULT WINAPI dddo_EnumFormatEtc(IDataObject* iface, DWORD direction, for (i = 0; i < count; i++) { - formatEtcs[i].cfFormat = (UINT)CFArrayGetValueAtIndex(formats, i); + formatEtcs[i].cfFormat = formats[i]; formatEtcs[i].ptd = NULL; formatEtcs[i].dwAspect = DVASPECT_CONTENT; formatEtcs[i].lindex = -1; @@ -220,7 +219,7 @@ static HRESULT WINAPI dddo_EnumFormatEtc(IDataObject* iface, DWORD direction, else hr = E_OUTOFMEMORY; - CFRelease(formats); + HeapFree(GetProcessHeap(), 0, formats); } else hr = SHCreateStdEnumFmtEtc(0, NULL, enumFormatEtc); diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index bfdffc8..c29ea15 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -199,7 +199,7 @@ static inline RECT rect_from_cgrect(CGRect cgrect) extern const char *debugstr_format(UINT id) DECLSPEC_HIDDEN; extern HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format) DECLSPEC_HIDDEN; extern BOOL macdrv_pasteboard_has_format(CFTypeRef pasteboard, UINT desired_format) DECLSPEC_HIDDEN; -extern CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) DECLSPEC_HIDDEN; +extern UINT* macdrv_get_pasteboard_formats(CFTypeRef pasteboard, UINT* num_formats) DECLSPEC_HIDDEN; extern BOOL query_drag_operation(macdrv_query* query) DECLSPEC_HIDDEN; extern BOOL query_drag_exited(macdrv_query* query) DECLSPEC_HIDDEN; -- 2.8.2 From ken at codeweavers.com Sun Oct 23 13:03:32 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:32 -0500 Subject: [PATCH 13/15] winemac: Run a single clipboard manager thread per window station, inside the explorer process. In-Reply-To: <1477245814-49846-1-git-send-email-ken@codeweavers.com> References: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Message-ID: <1477245814-49846-13-git-send-email-ken@codeweavers.com> Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 399 ++++++++++++++++++++++++++++++++++------- dlls/winemac.drv/macdrv.h | 2 +- dlls/winemac.drv/macdrv_main.c | 2 - dlls/winemac.drv/window.c | 2 + 4 files changed, 336 insertions(+), 69 deletions(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index eba426a..936fa21 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -188,6 +188,14 @@ static const struct /* The prefix prepended to a Win32 clipboard format name to make a Mac pasteboard type. */ static const CFStringRef registered_name_type_prefix = CFSTR("org.winehq.registered."); +static DWORD clipboard_thread_id; +static HWND clipboard_hwnd; +static BOOL is_clipboard_owner; +static macdrv_window clipboard_cocoa_window; +static ULONG64 last_clipboard_update; +static WINE_CLIPFORMAT **current_mac_formats; +static unsigned int nb_current_mac_formats; + /************************************************************************** * Internal Clipboard implementation methods @@ -302,6 +310,69 @@ static WINE_CLIPFORMAT* register_format(UINT id, CFStringRef type) /************************************************************************** + * natural_format_for_format + * + * Find the "natural" format for this format_id (the one which isn't + * synthesized from another type). + */ +static WINE_CLIPFORMAT* natural_format_for_format(UINT format_id) +{ + WINE_CLIPFORMAT *format; + + LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry) + if (format->format_id == format_id && !format->synthesized) break; + + if (&format->entry == &format_list) + format = NULL; + + TRACE("%s -> %p/%s\n", debugstr_format(format_id), format, debugstr_cf(format ? format->type : NULL)); + return format; +} + + +/************************************************************************** + * register_builtin_formats + */ +static void register_builtin_formats(void) +{ + UINT i; + WINE_CLIPFORMAT *format; + + /* Register built-in formats */ + for (i = 0; i < sizeof(builtin_format_ids)/sizeof(builtin_format_ids[0]); i++) + { + if (!(format = HeapAlloc(GetProcessHeap(), 0, sizeof(*format)))) break; + format->format_id = builtin_format_ids[i].id; + format->type = CFRetain(builtin_format_ids[i].type); + format->import_func = builtin_format_ids[i].import; + format->export_func = builtin_format_ids[i].export; + format->synthesized = builtin_format_ids[i].synthesized; + format->natural_format = NULL; + list_add_tail(&format_list, &format->entry); + } + + LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry) + { + if (format->synthesized) + format->natural_format = natural_format_for_format(format->format_id); + } + + /* Register known mappings between Windows formats and Mac types */ + for (i = 0; i < sizeof(builtin_format_names)/sizeof(builtin_format_names[0]); i++) + { + if (!(format = HeapAlloc(GetProcessHeap(), 0, sizeof(*format)))) break; + format->format_id = RegisterClipboardFormatW(builtin_format_names[i].name); + format->type = CFRetain(builtin_format_names[i].type); + format->import_func = builtin_format_names[i].import; + format->export_func = builtin_format_names[i].export; + format->synthesized = FALSE; + format->natural_format = NULL; + list_add_tail(&format_list, &format->entry); + } +} + + +/************************************************************************** * format_for_type */ static WINE_CLIPFORMAT* format_for_type(CFStringRef type) @@ -310,6 +381,8 @@ static WINE_CLIPFORMAT* format_for_type(CFStringRef type) TRACE("type %s\n", debugstr_cf(type)); + if (list_empty(&format_list)) register_builtin_formats(); + LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry) { if (CFEqual(format->type, type)) @@ -345,27 +418,6 @@ done: } -/************************************************************************** - * natural_format_for_format - * - * Find the "natural" format for this format_id (the one which isn't - * synthesized from another type). - */ -static WINE_CLIPFORMAT* natural_format_for_format(UINT format_id) -{ - WINE_CLIPFORMAT *format; - - LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry) - if (format->format_id == format_id && !format->synthesized) break; - - if (&format->entry == &format_list) - format = NULL; - - TRACE("%s -> %p/%s\n", debugstr_format(format_id), format, debugstr_cf(format ? format->type : NULL)); - return format; -} - - /*********************************************************************** * bitmap_info_size * @@ -1448,6 +1500,250 @@ UINT* macdrv_get_pasteboard_formats(CFTypeRef pasteboard, UINT* num_formats) /************************************************************************** + * register_win32_formats + * + * Register Win32 clipboard formats the first time we encounter them. + */ +static void register_win32_formats(const UINT *ids, UINT size) +{ + unsigned int i; + + if (list_empty(&format_list)) register_builtin_formats(); + + for (i = 0; i < size; i++) + register_format(ids[i], NULL); +} + + +/*********************************************************************** + * get_clipboard_formats + * + * Return a list of all formats currently available on the Win32 clipboard. + * Helper for set_mac_pasteboard_types_from_win32_clipboard. + */ +static UINT *get_clipboard_formats(UINT *size) +{ + UINT *ids; + + *size = 256; + for (;;) + { + if (!(ids = HeapAlloc(GetProcessHeap(), 0, *size * sizeof(*ids)))) return NULL; + if (GetUpdatedClipboardFormats(ids, *size, size)) break; + HeapFree(GetProcessHeap(), 0, ids); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return NULL; + } + register_win32_formats(ids, *size); + return ids; +} + + +/************************************************************************** + * set_mac_pasteboard_types_from_win32_clipboard + */ +static void set_mac_pasteboard_types_from_win32_clipboard(void) +{ + WINE_CLIPFORMAT *format; + UINT count, i, *formats; + + if (!(formats = get_clipboard_formats(&count))) return; + + macdrv_clear_pasteboard(); + + for (i = 0; i < count; i++) + { + LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry) + { + if (format->format_id != formats[i]) continue; + TRACE("%s -> %s\n", debugstr_format(format->format_id), debugstr_cf(format->type)); + macdrv_set_pasteboard_data(format->type, NULL, clipboard_cocoa_window); + } + } + + HeapFree(GetProcessHeap(), 0, formats); + return; +} + + +/************************************************************************** + * set_win32_clipboard_formats_from_mac_pasteboard + */ +static void set_win32_clipboard_formats_from_mac_pasteboard(void) +{ + WINE_CLIPFORMAT** formats; + UINT count, i; + + formats = get_formats_for_pasteboard(NULL, &count); + if (!formats) + return; + + for (i = 0; i < count; i++) + { + TRACE("adding format %s\n", debugstr_format(formats[i]->format_id)); + SetClipboardData(formats[i]->format_id, 0); + } + + HeapFree(GetProcessHeap(), 0, current_mac_formats); + current_mac_formats = formats; + nb_current_mac_formats = count; +} + + +/************************************************************************** + * render_format + */ +static void render_format(UINT id) +{ + unsigned int i; + + for (i = 0; i < nb_current_mac_formats; i++) + { + CFDataRef pasteboard_data; + + if (current_mac_formats[i]->format_id != id) continue; + + pasteboard_data = macdrv_copy_pasteboard_data(NULL, current_mac_formats[i]->type); + if (pasteboard_data) + { + HANDLE handle = current_mac_formats[i]->import_func(pasteboard_data); + CFRelease(pasteboard_data); + if (handle) SetClipboardData(id, handle); + break; + } + } +} + + +/************************************************************************** + * grab_win32_clipboard + * + * Grab the Win32 clipboard when a Mac app has taken ownership of the + * pasteboard, and fill it with the pasteboard data types. + */ +static BOOL grab_win32_clipboard(void) +{ + if (!OpenClipboard(clipboard_hwnd)) return FALSE; + EmptyClipboard(); + is_clipboard_owner = TRUE; + last_clipboard_update = GetTickCount64(); + set_win32_clipboard_formats_from_mac_pasteboard(); + CloseClipboard(); + return TRUE; +} + + +/************************************************************************** + * clipboard_wndproc + * + * Window procedure for the clipboard manager. + */ +static LRESULT CALLBACK clipboard_wndproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) +{ + switch (msg) + { + case WM_NCCREATE: + return TRUE; + case WM_CLIPBOARDUPDATE: + if (is_clipboard_owner) break; /* ignore our own changes */ + set_mac_pasteboard_types_from_win32_clipboard(); + break; + case WM_RENDERFORMAT: + render_format(wp); + break; + case WM_DESTROYCLIPBOARD: + TRACE("WM_DESTROYCLIPBOARD: lost ownership\n"); + is_clipboard_owner = FALSE; + break; + } + return DefWindowProcW(hwnd, msg, wp, lp); +} + + +/************************************************************************** + * wait_clipboard_mutex + * + * Make sure that there's only one clipboard thread per window station. + */ +static BOOL wait_clipboard_mutex(void) +{ + static const WCHAR prefix[] = {'_','_','w','i','n','e','_','c','l','i','p','b','o','a','r','d','_'}; + WCHAR buffer[MAX_PATH + sizeof(prefix) / sizeof(WCHAR)]; + HANDLE mutex; + + memcpy(buffer, prefix, sizeof(prefix)); + if (!GetUserObjectInformationW(GetProcessWindowStation(), UOI_NAME, + buffer + sizeof(prefix) / sizeof(WCHAR), + sizeof(buffer) - sizeof(prefix), NULL)) + { + ERR("failed to get winstation name\n"); + return FALSE; + } + mutex = CreateMutexW(NULL, TRUE, buffer); + if (GetLastError() == ERROR_ALREADY_EXISTS) + { + TRACE("waiting for mutex %s\n", debugstr_w(buffer)); + WaitForSingleObject(mutex, INFINITE); + } + return TRUE; +} + + +/************************************************************************** + * clipboard_thread + * + * Thread running inside the desktop process to manage the clipboard + */ +static DWORD WINAPI clipboard_thread(void *arg) +{ + static const WCHAR clipboard_classname[] = {'_','_','w','i','n','e','_','c','l','i','p','b','o','a','r','d','_','m','a','n','a','g','e','r',0}; + WNDCLASSW class; + struct macdrv_window_features wf; + MSG msg; + + if (!wait_clipboard_mutex()) return 0; + + memset(&class, 0, sizeof(class)); + class.lpfnWndProc = clipboard_wndproc; + class.lpszClassName = clipboard_classname; + + if (!RegisterClassW(&class) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) + { + ERR("could not register clipboard window class err %u\n", GetLastError()); + return 0; + } + if (!(clipboard_hwnd = CreateWindowW(clipboard_classname, NULL, 0, 0, 0, 0, 0, + HWND_MESSAGE, 0, 0, NULL))) + { + ERR("failed to create clipboard window err %u\n", GetLastError()); + return 0; + } + + memset(&wf, 0, sizeof(wf)); + clipboard_cocoa_window = macdrv_create_cocoa_window(&wf, CGRectMake(100, 100, 100, 100), clipboard_hwnd, + macdrv_init_thread_data()->queue); + if (!clipboard_cocoa_window) + { + ERR("failed to create clipboard Cocoa window\n"); + goto done; + } + + clipboard_thread_id = GetCurrentThreadId(); + AddClipboardFormatListener(clipboard_hwnd); + register_builtin_formats(); + grab_win32_clipboard(); + + TRACE("clipboard thread %04x running\n", GetCurrentThreadId()); + while (GetMessageW(&msg, NULL, 0, 0)) + DispatchMessageW(&msg); + +done: + macdrv_destroy_cocoa_window(clipboard_cocoa_window); + DestroyWindow(clipboard_hwnd); + return 0; +} + + +/************************************************************************** * Mac User Driver Clipboard Exports **************************************************************************/ @@ -1458,48 +1754,6 @@ UINT* macdrv_get_pasteboard_formats(CFTypeRef pasteboard, UINT* num_formats) /************************************************************************** - * macdrv_clipboard_process_attach - */ -void macdrv_clipboard_process_attach(void) -{ - UINT i; - WINE_CLIPFORMAT *format; - - /* Register built-in formats */ - for (i = 0; i < sizeof(builtin_format_ids)/sizeof(builtin_format_ids[0]); i++) - { - if (!(format = HeapAlloc(GetProcessHeap(), 0, sizeof(*format)))) break; - format->format_id = builtin_format_ids[i].id; - format->type = CFRetain(builtin_format_ids[i].type); - format->import_func = builtin_format_ids[i].import; - format->export_func = builtin_format_ids[i].export; - format->synthesized = builtin_format_ids[i].synthesized; - format->natural_format = NULL; - list_add_tail(&format_list, &format->entry); - } - - LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry) - { - if (format->synthesized) - format->natural_format = natural_format_for_format(format->format_id); - } - - /* Register known mappings between Windows formats and Mac types */ - for (i = 0; i < sizeof(builtin_format_names)/sizeof(builtin_format_names[0]); i++) - { - if (!(format = HeapAlloc(GetProcessHeap(), 0, sizeof(*format)))) break; - format->format_id = RegisterClipboardFormatW(builtin_format_names[i].name); - format->type = CFRetain(builtin_format_names[i].type); - format->import_func = builtin_format_names[i].import; - format->export_func = builtin_format_names[i].export; - format->synthesized = FALSE; - format->natural_format = NULL; - list_add_tail(&format_list, &format->entry); - } -} - - -/************************************************************************** * query_pasteboard_data */ BOOL query_pasteboard_data(HWND hwnd, CFStringRef type) @@ -1508,12 +1762,12 @@ BOOL query_pasteboard_data(HWND hwnd, CFStringRef type) BOOL ret = FALSE; HANDLE handle; - TRACE("win %p type %s\n", hwnd, debugstr_cf(type)); + TRACE("win %p/%p type %s\n", hwnd, clipboard_cocoa_window, debugstr_cf(type)); format = format_for_type(type); if (!format) return FALSE; - if (!OpenClipboard(NULL)) + if (!OpenClipboard(clipboard_hwnd)) { ERR("failed to open clipboard for %s\n", debugstr_cf(type)); return FALSE; @@ -1527,7 +1781,7 @@ BOOL query_pasteboard_data(HWND hwnd, CFStringRef type) if ((data = format->export_func(handle))) { - ret = macdrv_set_pasteboard_data(format->type, data, macdrv_get_cocoa_window(hwnd, FALSE)); + ret = macdrv_set_pasteboard_data(format->type, data, clipboard_cocoa_window); CFRelease(data); } } @@ -1536,3 +1790,16 @@ BOOL query_pasteboard_data(HWND hwnd, CFStringRef type) return ret; } + + +/************************************************************************** + * macdrv_init_clipboard + */ +void macdrv_init_clipboard(void) +{ + DWORD id; + HANDLE handle = CreateThread(NULL, 0, clipboard_thread, NULL, 0, &id); + + if (handle) CloseHandle(handle); + else ERR("failed to create clipboard thread\n"); +} diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index c29ea15..8afd064 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -194,7 +194,7 @@ static inline RECT rect_from_cgrect(CGRect cgrect) extern void macdrv_displays_changed(const macdrv_event *event) DECLSPEC_HIDDEN; -extern void macdrv_clipboard_process_attach(void) DECLSPEC_HIDDEN; +extern void macdrv_init_clipboard(void) DECLSPEC_HIDDEN; extern BOOL query_pasteboard_data(HWND hwnd, CFStringRef type) DECLSPEC_HIDDEN; extern const char *debugstr_format(UINT id) DECLSPEC_HIDDEN; extern HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format) DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c index 3b11751..491ab06 100644 --- a/dlls/winemac.drv/macdrv_main.c +++ b/dlls/winemac.drv/macdrv_main.c @@ -283,8 +283,6 @@ static BOOL process_attach(void) return FALSE; } - macdrv_clipboard_process_attach(); - return TRUE; } diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 0359ef7..07d0f23 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1480,6 +1480,8 @@ BOOL CDECL macdrv_CreateDesktopWindow(HWND hwnd) */ BOOL CDECL macdrv_CreateWindow(HWND hwnd) { + if (hwnd == GetDesktopWindow()) + macdrv_init_clipboard(); return TRUE; } -- 2.8.2 From ken at codeweavers.com Sun Oct 23 13:03:33 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:33 -0500 Subject: [PATCH 14/15] winemac: Implement the UpdateClipboard entry point to have the clipboard manager update its status. In-Reply-To: <1477245814-49846-1-git-send-email-ken@codeweavers.com> References: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Message-ID: <1477245814-49846-14-git-send-email-ken@codeweavers.com> Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 291 +++++++++++++++++++++++++++++++++++++- dlls/winemac.drv/winemac.drv.spec | 1 + 2 files changed, 290 insertions(+), 2 deletions(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index 936fa21..358794d 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -59,6 +59,8 @@ typedef struct _WINE_CLIPFORMAT * Constants **************************************************************************/ +#define CLIPBOARD_UPDATE_DELAY 2000 /* delay between checks of the Mac pasteboard */ + /************************************************************************** * Forward Function Declarations @@ -195,6 +197,7 @@ static macdrv_window clipboard_cocoa_window; static ULONG64 last_clipboard_update; static WINE_CLIPFORMAT **current_mac_formats; static unsigned int nb_current_mac_formats; +static WCHAR clipboard_pipe_name[256]; /************************************************************************** @@ -1633,6 +1636,36 @@ static BOOL grab_win32_clipboard(void) /************************************************************************** + * update_clipboard + * + * Periodically update the clipboard while the clipboard is owned by a + * Mac app. + */ +static BOOL update_clipboard(void) +{ + static BOOL updating; + BOOL ret = TRUE; + + TRACE("is_clipboard_owner %d last_clipboard_update %llu now %llu\n", + is_clipboard_owner, last_clipboard_update, GetTickCount64()); + + if (updating) return TRUE; + updating = TRUE; + + if (is_clipboard_owner) + { + if (GetTickCount64() - last_clipboard_update > CLIPBOARD_UPDATE_DELAY) + ret = grab_win32_clipboard(); + } + else if (!macdrv_is_pasteboard_owner()) + ret = grab_win32_clipboard(); + + updating = FALSE; + return ret; +} + + +/************************************************************************** * clipboard_wndproc * * Window procedure for the clipboard manager. @@ -1689,6 +1722,42 @@ static BOOL wait_clipboard_mutex(void) /************************************************************************** + * init_pipe_name + * + * Init-once helper for get_pipe_name. + */ +static BOOL CALLBACK init_pipe_name(INIT_ONCE* once, void* param, void** context) +{ + static const WCHAR prefix[] = {'\\','\\','.','\\','p','i','p','e','\\','_','_','w','i','n','e','_','c','l','i','p','b','o','a','r','d','_'}; + + memcpy(clipboard_pipe_name, prefix, sizeof(prefix)); + if (!GetUserObjectInformationW(GetProcessWindowStation(), UOI_NAME, + clipboard_pipe_name + sizeof(prefix) / sizeof(WCHAR), + sizeof(clipboard_pipe_name) - sizeof(prefix), NULL)) + { + ERR("failed to get winstation name\n"); + return FALSE; + } + + return TRUE; +} + + +/************************************************************************** + * get_pipe_name + * + * Get the name of the pipe used to communicate with the per-window-station + * clipboard manager thread. + */ +static const WCHAR* get_pipe_name(void) +{ + static INIT_ONCE once = INIT_ONCE_STATIC_INIT; + InitOnceExecuteOnce(&once, init_pipe_name, NULL, NULL); + return clipboard_pipe_name[0] ? clipboard_pipe_name : NULL; +} + + +/************************************************************************** * clipboard_thread * * Thread running inside the desktop process to manage the clipboard @@ -1698,6 +1767,11 @@ static DWORD WINAPI clipboard_thread(void *arg) static const WCHAR clipboard_classname[] = {'_','_','w','i','n','e','_','c','l','i','p','b','o','a','r','d','_','m','a','n','a','g','e','r',0}; WNDCLASSW class; struct macdrv_window_features wf; + const WCHAR* pipe_name; + HANDLE pipe = NULL; + HANDLE event = NULL; + OVERLAPPED overlapped; + BOOL need_connect = TRUE, pending = FALSE; MSG msg; if (!wait_clipboard_mutex()) return 0; @@ -1727,16 +1801,103 @@ static DWORD WINAPI clipboard_thread(void *arg) goto done; } + pipe_name = get_pipe_name(); + if (!pipe_name) + { + ERR("failed to get pipe name\n"); + goto done; + } + + pipe = CreateNamedPipeW(pipe_name, PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, 1, 1, 0, NULL); + if (!pipe) + { + ERR("failed to create named pipe: %u\n", GetLastError()); + goto done; + } + + event = CreateEventW(NULL, TRUE, FALSE, NULL); + if (!event) + { + ERR("failed to create event: %d\n", GetLastError()); + goto done; + } + clipboard_thread_id = GetCurrentThreadId(); AddClipboardFormatListener(clipboard_hwnd); register_builtin_formats(); grab_win32_clipboard(); TRACE("clipboard thread %04x running\n", GetCurrentThreadId()); - while (GetMessageW(&msg, NULL, 0, 0)) - DispatchMessageW(&msg); + while (1) + { + DWORD result; + + if (need_connect) + { + pending = FALSE; + memset(&overlapped, 0, sizeof(overlapped)); + overlapped.hEvent = event; + if (ConnectNamedPipe(pipe, &overlapped)) + { + ERR("asynchronous ConnectNamedPipe unexpectedly returned true: %d\n", GetLastError()); + ResetEvent(event); + } + else + { + result = GetLastError(); + switch (result) + { + case ERROR_PIPE_CONNECTED: + case ERROR_NO_DATA: + SetEvent(event); + need_connect = FALSE; + break; + case ERROR_IO_PENDING: + need_connect = FALSE; + pending = TRUE; + break; + default: + ERR("failed to initiate pipe connection: %d\n", result); + break; + } + } + } + + result = MsgWaitForMultipleObjectsEx(1, &event, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE); + switch (result) + { + case WAIT_OBJECT_0: + { + DWORD written; + + if (pending && !GetOverlappedResult(pipe, &overlapped, &written, FALSE)) + ERR("failed to connect pipe: %d\n", GetLastError()); + + update_clipboard(); + DisconnectNamedPipe(pipe); + need_connect = TRUE; + break; + } + case WAIT_OBJECT_0 + 1: + while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) + { + if (msg.message == WM_QUIT) + goto done; + DispatchMessageW(&msg); + } + break; + case WAIT_IO_COMPLETION: + break; + default: + ERR("failed to wait for connection or input: %d\n", GetLastError()); + break; + } + } done: + if (event) CloseHandle(event); + if (pipe) CloseHandle(pipe); macdrv_destroy_cocoa_window(clipboard_cocoa_window); DestroyWindow(clipboard_hwnd); return 0; @@ -1749,6 +1910,132 @@ done: /************************************************************************** + * macdrv_UpdateClipboard + */ +void CDECL macdrv_UpdateClipboard(void) +{ + static ULONG last_update; + ULONG now, end; + const WCHAR* pipe_name; + HANDLE pipe; + BYTE dummy; + DWORD count; + OVERLAPPED overlapped = { 0 }; + BOOL canceled = FALSE; + + if (GetCurrentThreadId() == clipboard_thread_id) return; + + TRACE("\n"); + + now = GetTickCount(); + if ((int)(now - last_update) <= CLIPBOARD_UPDATE_DELAY) return; + last_update = now; + + if (!(pipe_name = get_pipe_name())) return; + pipe = CreateFileW(pipe_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); + if (!pipe) + { + WARN("failed to open pipe to clipboard manager: %d\n", GetLastError()); + return; + } + + overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + if (!overlapped.hEvent) + { + ERR("failed to create event: %d\n", GetLastError()); + goto done; + } + + /* We expect the read to fail because the server just closes our connection. This + is just waiting for that close to happen. */ + if (ReadFile(pipe, &dummy, sizeof(dummy), NULL, &overlapped)) + { + WARN("asynchronous ReadFile unexpectedly returned true: %d\n", GetLastError()); + goto done; + } + else + { + DWORD error = GetLastError(); + if (error == ERROR_PIPE_NOT_CONNECTED || error == ERROR_BROKEN_PIPE) + { + /* The server accepted, handled, and closed our connection before we + attempted the read, which is fine. */ + goto done; + } + else if (error != ERROR_IO_PENDING) + { + ERR("failed to initiate read from pipe: %d\n", error); + goto done; + } + } + + end = now + 500; + while (1) + { + DWORD result, timeout; + + if (canceled) + timeout = INFINITE; + else + { + now = GetTickCount(); + timeout = end - now; + if ((int)timeout < 0) + timeout = 0; + } + + result = MsgWaitForMultipleObjectsEx(1, &overlapped.hEvent, timeout, QS_SENDMESSAGE, MWMO_ALERTABLE); + switch (result) + { + case WAIT_OBJECT_0: + { + if (GetOverlappedResult(pipe, &overlapped, &count, FALSE)) + WARN("unexpectedly succeeded in reading from pipe\n"); + else + { + result = GetLastError(); + if (result != ERROR_BROKEN_PIPE && result != ERROR_OPERATION_ABORTED) + WARN("failed to read from pipe: %d\n", result); + } + + goto done; + } + case WAIT_OBJECT_0 + 1: + { + MSG msg; + while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE)) + DispatchMessageW(&msg); + break; + } + case WAIT_IO_COMPLETION: + break; + case WAIT_TIMEOUT: + WARN("timed out waiting for read\n"); + CancelIoEx(pipe, &overlapped); + canceled = TRUE; + break; + default: + if (canceled) + { + ERR("failed to wait for cancel: %d\n", GetLastError()); + goto done; + } + + ERR("failed to wait for read: %d\n", GetLastError()); + CancelIoEx(pipe, &overlapped); + canceled = TRUE; + break; + } + } + +done: + if (overlapped.hEvent) CloseHandle(overlapped.hEvent); + CloseHandle(pipe); +} + + +/************************************************************************** * MACDRV Private Clipboard Exports **************************************************************************/ diff --git a/dlls/winemac.drv/winemac.drv.spec b/dlls/winemac.drv/winemac.drv.spec index 3e6619e..6fa723a 100644 --- a/dlls/winemac.drv/winemac.drv.spec +++ b/dlls/winemac.drv/winemac.drv.spec @@ -38,6 +38,7 @@ @ cdecl ThreadDetach() macdrv_ThreadDetach @ cdecl ToUnicodeEx(long long ptr ptr long long long) macdrv_ToUnicodeEx @ cdecl UnregisterHotKey(long long long) macdrv_UnregisterHotKey +@ cdecl UpdateClipboard() macdrv_UpdateClipboard @ cdecl UpdateLayeredWindow(long ptr ptr) macdrv_UpdateLayeredWindow @ cdecl VkKeyScanEx(long long) macdrv_VkKeyScanEx @ cdecl WindowMessage(long long long long) macdrv_WindowMessage -- 2.8.2 From ken at codeweavers.com Sun Oct 23 13:03:34 2016 From: ken at codeweavers.com (Ken Thomases) Date: Sun, 23 Oct 2016 13:03:34 -0500 Subject: [PATCH 15/15] winemac: Detect loss of ownership of the Mac pasteboard and update the clipboard manager status. In-Reply-To: <1477245814-49846-1-git-send-email-ken@codeweavers.com> References: <1477245814-49846-1-git-send-email-ken@codeweavers.com> Message-ID: <1477245814-49846-15-git-send-email-ken@codeweavers.com> Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 17 +++++++++++++++-- dlls/winemac.drv/cocoa_clipboard.m | 20 ++++++++++++++++---- dlls/winemac.drv/cocoa_window.m | 7 +++++++ dlls/winemac.drv/event.c | 5 +++++ dlls/winemac.drv/macdrv.h | 1 + dlls/winemac.drv/macdrv_cocoa.h | 5 +++-- 6 files changed, 47 insertions(+), 8 deletions(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index 358794d..fc0d60c 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -1551,7 +1551,7 @@ static void set_mac_pasteboard_types_from_win32_clipboard(void) if (!(formats = get_clipboard_formats(&count))) return; - macdrv_clear_pasteboard(); + macdrv_clear_pasteboard(clipboard_cocoa_window); for (i = 0; i < count; i++) { @@ -1657,7 +1657,7 @@ static BOOL update_clipboard(void) if (GetTickCount64() - last_clipboard_update > CLIPBOARD_UPDATE_DELAY) ret = grab_win32_clipboard(); } - else if (!macdrv_is_pasteboard_owner()) + else if (!macdrv_is_pasteboard_owner(clipboard_cocoa_window)) ret = grab_win32_clipboard(); updating = FALSE; @@ -2080,6 +2080,19 @@ BOOL query_pasteboard_data(HWND hwnd, CFStringRef type) /************************************************************************** + * macdrv_lost_pasteboard_ownership + * + * Handler for the LOST_PASTEBOARD_OWNERSHIP event. + */ +void macdrv_lost_pasteboard_ownership(HWND hwnd) +{ + TRACE("win %p\n", hwnd); + if (!macdrv_is_pasteboard_owner(clipboard_cocoa_window)) + grab_win32_clipboard(); +} + + +/************************************************************************** * macdrv_init_clipboard */ void macdrv_init_clipboard(void) diff --git a/dlls/winemac.drv/cocoa_clipboard.m b/dlls/winemac.drv/cocoa_clipboard.m index 1d1cb88..3b6ec41 100644 --- a/dlls/winemac.drv/cocoa_clipboard.m +++ b/dlls/winemac.drv/cocoa_clipboard.m @@ -21,6 +21,7 @@ #include "macdrv_cocoa.h" #import "cocoa_app.h" #import "cocoa_event.h" +#import "cocoa_window.h" static int owned_change_count = -1; @@ -29,17 +30,23 @@ static NSDictionary* BitmapOutputTypeMap; static dispatch_once_t BitmapOutputTypesInitOnce; +static NSString* const OwnershipSentinel = @"org.winehq.wine.winemac.pasteboard-ownership-sentinel"; + /*********************************************************************** * macdrv_is_pasteboard_owner */ -int macdrv_is_pasteboard_owner(void) +int macdrv_is_pasteboard_owner(macdrv_window w) { __block int ret; + WineWindow* window = (WineWindow*)w; OnMainThread(^{ NSPasteboard* pb = [NSPasteboard generalPasteboard]; ret = ([pb changeCount] == owned_change_count); + + [window.queue discardEventsMatchingMask:event_mask_for_type(LOST_PASTEBOARD_OWNERSHIP) + forWindow:window]; }); return ret; @@ -157,13 +164,18 @@ CFDataRef macdrv_copy_pasteboard_data(CFTypeRef pasteboard, CFStringRef type) * * Takes ownership of the Mac pasteboard and clears it of all data types. */ -void macdrv_clear_pasteboard(void) +void macdrv_clear_pasteboard(macdrv_window w) { - OnMainThreadAsync(^{ + WineWindow* window = (WineWindow*)w; + + OnMainThread(^{ @try { NSPasteboard* pb = [NSPasteboard generalPasteboard]; - owned_change_count = [pb declareTypes:[NSArray array] owner:nil]; + owned_change_count = [pb declareTypes:[NSArray arrayWithObject:OwnershipSentinel] + owner:window]; + [window.queue discardEventsMatchingMask:event_mask_for_type(LOST_PASTEBOARD_OWNERSHIP) + forWindow:window]; } @catch (id e) { diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index e638991..a68ba03 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -2824,6 +2824,13 @@ - (void) pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type macdrv_release_query(query); } + - (void) pasteboardChangedOwner:(NSPasteboard*)sender + { + macdrv_event* event = macdrv_create_event(LOST_PASTEBOARD_OWNERSHIP, self); + [queue postEvent:event]; + macdrv_release_event(event); + } + /* * ---------- NSDraggingDestination methods ---------- diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c index 2b3d6ce..7d3aab3 100644 --- a/dlls/winemac.drv/event.c +++ b/dlls/winemac.drv/event.c @@ -40,6 +40,7 @@ static const char *dbgstr_event(int type) "KEY_PRESS", "KEY_RELEASE", "KEYBOARD_CHANGED", + "LOST_PASTEBOARD_OWNERSHIP", "MOUSE_BUTTON", "MOUSE_MOVED", "MOUSE_MOVED_ABSOLUTE", @@ -107,6 +108,7 @@ static macdrv_event_mask get_event_mask(DWORD mask) event_mask |= event_mask_for_type(APP_QUIT_REQUESTED); event_mask |= event_mask_for_type(DISPLAYS_CHANGED); event_mask |= event_mask_for_type(IM_SET_TEXT); + event_mask |= event_mask_for_type(LOST_PASTEBOARD_OWNERSHIP); event_mask |= event_mask_for_type(STATUS_ITEM_MOUSE_BUTTON); event_mask |= event_mask_for_type(STATUS_ITEM_MOUSE_MOVE); event_mask |= event_mask_for_type(WINDOW_DID_UNMINIMIZE); @@ -230,6 +232,9 @@ void macdrv_handle_event(const macdrv_event *event) case KEYBOARD_CHANGED: macdrv_keyboard_changed(event); break; + case LOST_PASTEBOARD_OWNERSHIP: + macdrv_lost_pasteboard_ownership(hwnd); + break; case MOUSE_BUTTON: macdrv_mouse_button(hwnd, event); break; diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 8afd064..a3ded73 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -196,6 +196,7 @@ static inline RECT rect_from_cgrect(CGRect cgrect) extern void macdrv_init_clipboard(void) DECLSPEC_HIDDEN; extern BOOL query_pasteboard_data(HWND hwnd, CFStringRef type) DECLSPEC_HIDDEN; +extern void macdrv_lost_pasteboard_ownership(HWND hwnd) DECLSPEC_HIDDEN; extern const char *debugstr_format(UINT id) DECLSPEC_HIDDEN; extern HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format) DECLSPEC_HIDDEN; extern BOOL macdrv_pasteboard_has_format(CFTypeRef pasteboard, UINT desired_format) DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index b3e9106..21e9565 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -267,6 +267,7 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display, KEY_PRESS, KEY_RELEASE, KEYBOARD_CHANGED, + LOST_PASTEBOARD_OWNERSHIP, MOUSE_BUTTON, MOUSE_MOVED, MOUSE_MOVED_ABSOLUTE, @@ -539,8 +540,8 @@ extern void macdrv_get_input_source_info(CFDataRef* uchr,CGEventSourceKeyboardTy /* clipboard */ extern CFArrayRef macdrv_copy_pasteboard_types(CFTypeRef pasteboard) DECLSPEC_HIDDEN; extern CFDataRef macdrv_copy_pasteboard_data(CFTypeRef pasteboard, CFStringRef type) DECLSPEC_HIDDEN; -extern int macdrv_is_pasteboard_owner(void) DECLSPEC_HIDDEN; -extern void macdrv_clear_pasteboard(void) DECLSPEC_HIDDEN; +extern int macdrv_is_pasteboard_owner(macdrv_window w) DECLSPEC_HIDDEN; +extern void macdrv_clear_pasteboard(macdrv_window w) DECLSPEC_HIDDEN; extern int macdrv_set_pasteboard_data(CFStringRef type, CFDataRef data, macdrv_window w) DECLSPEC_HIDDEN; -- 2.8.2 From hans at codeweavers.com Mon Oct 24 03:03:48 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Mon, 24 Oct 2016 10:03:48 +0200 Subject: [PATCH] MSI: remove useless code. In-Reply-To: <1747463070.4193641477128635984.JavaMail.httpd@webmail-19.iol.local> References: <1747463070.4193641477128635984.JavaMail.httpd@webmail-19.iol.local> Message-ID: <1477296228.6573.388.camel@codeweavers.com> Signed-off-by: Hans Leidekker From hans at codeweavers.com Mon Oct 24 03:04:16 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Mon, 24 Oct 2016 10:04:16 +0200 Subject: advapi32: Avoid printing control characters in traces. Message-ID: <1477296261-28463-1-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/advapi32/eventlog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/advapi32/eventlog.c b/dlls/advapi32/eventlog.c index 893f6e5..e97ddc7 100644 --- a/dlls/advapi32/eventlog.c +++ b/dlls/advapi32/eventlog.c @@ -230,7 +230,7 @@ ULONG WINAPI EnableTraceEx( LPCGUID provider, LPCGUID source, TRACEHANDLE hSessi UCHAR level, ULONGLONG anykeyword, ULONGLONG allkeyword, ULONG enableprop, PEVENT_FILTER_DESCRIPTOR filterdesc ) { - FIXME("(%s, %s, %s, %d, %c, %s, %s, %d, %p): stub\n", debugstr_guid(provider), + FIXME("(%s, %s, %s, %u, %u, %s, %s, %u, %p): stub\n", debugstr_guid(provider), debugstr_guid(source), wine_dbgstr_longlong(hSession), enable, level, wine_dbgstr_longlong(anykeyword), wine_dbgstr_longlong(allkeyword), enableprop, filterdesc); @@ -245,7 +245,7 @@ ULONG WINAPI EnableTraceEx2( TRACEHANDLE handle, LPCGUID provider, ULONG control ULONGLONG match_any, ULONGLONG match_all, ULONG timeout, PENABLE_TRACE_PARAMETERS params ) { - FIXME("(%s, %s, %u, %c, %s, %s, %u, %p): stub\n", wine_dbgstr_longlong(handle), + FIXME("(%s, %s, %u, %u, %s, %s, %u, %p): stub\n", wine_dbgstr_longlong(handle), debugstr_guid(provider), control, level, wine_dbgstr_longlong(match_any), wine_dbgstr_longlong(match_all), timeout, params); -- 2.1.4 From hans at codeweavers.com Mon Oct 24 03:04:17 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Mon, 24 Oct 2016 10:04:17 +0200 Subject: davclnt: Return a fake handle from DavRegisterAuthCallback. Message-ID: <1477296261-28463-2-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/davclnt/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/davclnt/main.c b/dlls/davclnt/main.c index ac38697..8e0bf84 100644 --- a/dlls/davclnt/main.c +++ b/dlls/davclnt/main.c @@ -50,7 +50,7 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) OPAQUE_HANDLE WINAPI DavRegisterAuthCallback(PFNDAVAUTHCALLBACK cb, ULONG version) { FIXME("%p, %u\n", cb, version); - return 0; + return 0xdeadbeef; } /*********************************************************************** @@ -58,5 +58,5 @@ OPAQUE_HANDLE WINAPI DavRegisterAuthCallback(PFNDAVAUTHCALLBACK cb, ULONG versio */ VOID WINAPI DavUnregisterAuthCallback(OPAQUE_HANDLE handle) { - FIXME("%u\n", handle); + FIXME("%08x\n", handle); } -- 2.1.4 From hans at codeweavers.com Mon Oct 24 03:04:18 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Mon, 24 Oct 2016 10:04:18 +0200 Subject: include: Avoid redefinition of PEVENT_FILTER_DESCRIPTOR. Message-ID: <1477296261-28463-3-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- include/evntrace.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/include/evntrace.h b/include/evntrace.h index b54cd11..bb1ce03 100644 --- a/include/evntrace.h +++ b/include/evntrace.h @@ -248,16 +248,14 @@ typedef struct _EVENT_TRACE_PROPERTIES ULONG LoggerNameOffset; } EVENT_TRACE_PROPERTIES, *PEVENT_TRACE_PROPERTIES; -typedef struct _EVENT_FILTER_DESCRIPTOR *PEVENT_FILTER_DESCRIPTOR; - typedef struct _ENABLE_TRACE_PARAMETERS { - ULONG Version; - ULONG EnableProperty; - ULONG ControlFlags; - GUID SourceId; - PEVENT_FILTER_DESCRIPTOR EnableFilterDesc; - ULONG FilterDescCount; + ULONG Version; + ULONG EnableProperty; + ULONG ControlFlags; + GUID SourceId; + struct _EVENT_FILTER_DESCRIPTOR *EnableFilterDesc; + ULONG FilterDescCount; } ENABLE_TRACE_PARAMETERS, *PENABLE_TRACE_PARAMETERS; #define INVALID_PROCESSTRACE_HANDLE ((TRACEHANDLE)~(ULONG_PTR)0) -- 2.1.4 From hans at codeweavers.com Mon Oct 24 03:04:19 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Mon, 24 Oct 2016 10:04:19 +0200 Subject: netapi32: Implement DavGetUNCFromHTTPPath. Message-ID: <1477296261-28463-4-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/netapi32/netapi32.c | 85 ++++++++++++++++++++++++ dlls/netapi32/netapi32.spec | 1 + dlls/netapi32/tests/access.c | 153 +++++++++++++++++++++++++++++++++++++++++++ include/davclnt.h | 1 + 4 files changed, 240 insertions(+) diff --git a/dlls/netapi32/netapi32.c b/dlls/netapi32/netapi32.c index bb61e7f..278d452 100644 --- a/dlls/netapi32/netapi32.c +++ b/dlls/netapi32/netapi32.c @@ -3442,3 +3442,88 @@ DWORD WINAPI DavGetHTTPFromUNCPath(const WCHAR *unc_path, WCHAR *buf, DWORD *buf return ERROR_SUCCESS; } + +/************************************************************ + * DavGetUNCFromHTTPPath (NETAPI32.@) + */ +DWORD WINAPI DavGetUNCFromHTTPPath(const WCHAR *http_path, WCHAR *buf, DWORD *buflen) +{ + static const WCHAR httpW[] = {'h','t','t','p'}; + static const WCHAR httpsW[] = {'h','t','t','p','s'}; + static const WCHAR davrootW[] = {'\\','D','a','v','W','W','W','R','o','o','t'}; + static const WCHAR sslW[] = {'@','S','S','L'}; + static const WCHAR port80W[] = {'8','0'}; + static const WCHAR port443W[] = {'4','4','3'}; + const WCHAR *p = http_path, *server, *port = NULL, *path = NULL; + DWORD i, len = 0, len_server = 0, len_port = 0, len_path = 0; + BOOL ssl; + + TRACE("(%s %p %p)\n", debugstr_w(http_path), buf, buflen); + + while (*p && *p != ':') { p++; len++; }; + if (len == sizeof(httpW)/sizeof(httpW[0]) && !memicmpW( http_path, httpW, len )) ssl = FALSE; + else if (len == sizeof(httpsW)/sizeof(httpsW[0]) && !memicmpW( http_path, httpsW, len )) ssl = TRUE; + else return ERROR_INVALID_PARAMETER; + + if (p[0] != ':' || p[1] != '/' || p[2] != '/') return ERROR_INVALID_PARAMETER; + server = p += 3; + + while (*p && *p != ':' && *p != '/') { p++; len_server++; }; + if (!len_server) return ERROR_BAD_NET_NAME; + if (*p == ':') + { + port = ++p; + while (*p && isdigitW(*p)) { p++; len_port++; }; + if (len_port == 2 && !ssl && !memcmp( port, port80W, sizeof(port80W) )) port = NULL; + else if (len_port == 3 && ssl && !memcmp( port, port443W, sizeof(port443W) )) port = NULL; + path = p; + } + else if (*p == '/') path = p; + + while (*p) + { + if (p[0] == '/' && p[1] == '/') return ERROR_BAD_NET_NAME; + p++; len_path++; + } + if (len_path && path[len_path - 1] == '/') len_path--; + + len = len_server + 2; /* \\ */ + if (ssl) len += 4; /* @SSL */ + if (port) len += len_port + 1 /* @ */; + len += sizeof(davrootW)/sizeof(davrootW[0]); + len += len_path + 1; /* nul */ + + if (*buflen < len) + { + *buflen = len; + return ERROR_INSUFFICIENT_BUFFER; + } + + buf[0] = buf[1] = '\\'; + buf += 2; + memcpy( buf, server, len_server * sizeof(WCHAR) ); + buf += len_server; + if (ssl) + { + memcpy( buf, sslW, sizeof(sslW) ); + buf += 4; + } + if (port) + { + *buf++ = '@'; + memcpy( buf, port, len_port * sizeof(WCHAR) ); + buf += len_port; + } + memcpy( buf, davrootW, sizeof(davrootW) ); + buf += sizeof(davrootW)/sizeof(davrootW[0]); + for (i = 0; i < len_path; i++) + { + if (path[i] == '/') *buf++ = '\\'; + else *buf++ = path[i]; + } + + *buf = 0; + *buflen = len; + + return ERROR_SUCCESS; +} diff --git a/dlls/netapi32/netapi32.spec b/dlls/netapi32/netapi32.spec index 64314af..8dbd378 100644 --- a/dlls/netapi32/netapi32.spec +++ b/dlls/netapi32/netapi32.spec @@ -1,4 +1,5 @@ @ stdcall DavGetHTTPFromUNCPath(wstr ptr ptr) +@ stdcall DavGetUNCFromHTTPPath(wstr ptr ptr) @ stub DsAddressToSiteNames @ stub DsAddressToSiteNamesEx @ stub DsDeregisterDnsHostRecords diff --git a/dlls/netapi32/tests/access.c b/dlls/netapi32/tests/access.c index a57c564..f44a6d3 100644 --- a/dlls/netapi32/tests/access.c +++ b/dlls/netapi32/tests/access.c @@ -66,6 +66,7 @@ static NET_API_STATUS (WINAPI *pNetUserDel)(LPCWSTR,LPCWSTR); static NET_API_STATUS (WINAPI *pNetLocalGroupGetInfo)(LPCWSTR,LPCWSTR,DWORD,LPBYTE*); static NET_API_STATUS (WINAPI *pNetLocalGroupGetMembers)(LPCWSTR,LPCWSTR,DWORD,LPBYTE*,DWORD,LPDWORD,LPDWORD,PDWORD_PTR); static DWORD (WINAPI *pDavGetHTTPFromUNCPath)(LPCWSTR,LPWSTR,LPDWORD); +static DWORD (WINAPI *pDavGetUNCFromHTTPPath)(LPCWSTR,LPWSTR,LPDWORD); static BOOL init_access_tests(void) { @@ -550,6 +551,156 @@ static void test_DavGetHTTPFromUNCPath(void) } } +static void test_DavGetUNCFromHTTPPath(void) +{ + static const WCHAR path[] = + {0}; + static const WCHAR path2[] = + {'h','t','t','p',':','/','/','s','e','r','v','e','r','/','p','a','t','h',0}; + static const WCHAR path3[] = + {'h','t','t','p','s',':','/','/','s','e','r','v','e','r','/','p','a','t','h',0}; + static const WCHAR path4[] = + {'\\','\\','s','e','r','v','e','r',0}; + static const WCHAR path5[] = + {'\\','\\','s','e','r','v','e','r','\\','p','a','t','h',0}; + static const WCHAR path6[] = + {'\\','\\','h','t','t','p',':','/','/','s','e','r','v','e','r','/','p','a','t','h',0}; + static const WCHAR path7[] = + {'h','t','t','p',':','/','/',0}; + static const WCHAR path8[] = + {'h','t','t','p',':',0}; + static const WCHAR path9[] = + {'h','t','t','p',0}; + static const WCHAR path10[] = + {'h','t','t','p',':','s','e','r','v','e','r',0}; + static const WCHAR path11[] = + {'h','t','t','p',':','/','/','s','e','r','v','e','r',':','8','0',0}; + static const WCHAR path12[] = + {'h','t','t','p',':','/','/','s','e','r','v','e','r',':','8','1',0}; + static const WCHAR path13[] = + {'h','t','t','p','s',':','/','/','s','e','r','v','e','r',':','8','0',0}; + static const WCHAR path14[] = + {'H','T','T','P',':','/','/','s','e','r','v','e','r','/','p','a','t','h',0}; + static const WCHAR path15[] = + {'h','t','t','p',':','/','/','s','e','r','v','e','r',':','6','5','5','3','7',0}; + static const WCHAR path16[] = + {'h','t','t','p',':','/','/','s','e','r','v','e','r','/','p','a','t','h','/',0}; + static const WCHAR path17[] = + {'h','t','t','p',':','/','/','s','e','r','v','e','r','/','p','a','t','h','/','/',0}; + static const WCHAR path18[] = + {'h','t','t','p',':','/','/','s','e','r','v','e','r',':','/','p','a','t','h',0}; + static const WCHAR path19[] = + {'h','t','t','p',':','/','/','s','e','r','v','e','r',0}; + static const WCHAR path20[] = + {'h','t','t','p','s',':','/','/','s','e','r','v','e','r',':','4','4','3',0}; + static const WCHAR path21[] = + {'h','t','t','p','s',':','/','/','s','e','r','v','e','r',':','8','0',0}; + static const WCHAR result[] = + {'\\','\\','s','e','r','v','e','r','\\','D','a','v','W','W','W','R','o','o','t','\\','p','a','t','h',0}; + static const WCHAR result2[] = + {'\\','\\','s','e','r','v','e','r','@','S','S','L','\\','D','a','v','W','W','W','R','o','o','t','\\', + 'p','a','t','h',0}; + static const WCHAR result3[] = + {'\\','\\','s','e','r','v','e','r','\\','D','a','v','W','W','W','R','o','o','t',0}; + static const WCHAR result4[] = + {'\\','\\','s','e','r','v','e','r','@','8','1','\\','D','a','v','W','W','W','R','o','o','t',0}; + static const WCHAR result5[] = + {'\\','\\','s','e','r','v','e','r','@','S','S','L','@','8','0','\\','D','a','v','W','W','W','R','o','o','t',0}; + static const WCHAR result6[] = + {'\\','\\','s','e','r','v','e','r','@','6','5','5','3','7','\\','D','a','v','W','W','W','R','o','o','t',0}; + static const WCHAR result7[] = + {'\\','\\','s','e','r','v','e','r','@','\\','D','a','v','W','W','W','R','o','o','t','\\','p','a','t','h',0}; + static const WCHAR result8[] = + {'\\','\\','s','e','r','v','e','r','@','S','S','L','\\','D','a','v','W','W','W','R','o','o','t',0}; + static const WCHAR result9[] = + {'\\','\\','s','e','r','v','e','r','@','S','S','L','@','8','0','\\','D','a','v','W','W','W','R','o','o','t',0}; + static const struct + { + const WCHAR *path; + DWORD size; + DWORD ret; + const WCHAR *ret_path; + DWORD ret_size; + } + tests[] = + { + { path, MAX_PATH, ERROR_INVALID_PARAMETER, NULL, MAX_PATH }, + { path2, MAX_PATH, ERROR_SUCCESS, result, 25 }, + { path3, MAX_PATH, ERROR_SUCCESS, result2, 29 }, + { path4, MAX_PATH, ERROR_INVALID_PARAMETER, NULL, MAX_PATH }, + { path5, MAX_PATH, ERROR_INVALID_PARAMETER, NULL, MAX_PATH }, + { path6, MAX_PATH, ERROR_INVALID_PARAMETER, NULL, MAX_PATH }, + { path7, MAX_PATH, ERROR_BAD_NET_NAME, NULL, MAX_PATH }, + { path8, MAX_PATH, ERROR_INVALID_PARAMETER, NULL, MAX_PATH }, + { path9, MAX_PATH, ERROR_INVALID_PARAMETER, NULL, MAX_PATH }, + { path10, MAX_PATH, ERROR_INVALID_PARAMETER, NULL, MAX_PATH }, + { path11, MAX_PATH, ERROR_SUCCESS, result3, 20 }, + { path12, MAX_PATH, ERROR_SUCCESS, result4, 23 }, + { path13, MAX_PATH, ERROR_SUCCESS, result5, 27 }, + { path14, MAX_PATH, ERROR_SUCCESS, result, 25 }, + { path15, MAX_PATH, ERROR_SUCCESS, result6, 26 }, + { path16, MAX_PATH, ERROR_SUCCESS, result, 25 }, + { path17, MAX_PATH, ERROR_BAD_NET_NAME, NULL, MAX_PATH }, + { path18, MAX_PATH, ERROR_SUCCESS, result7, 26 }, + { path19, MAX_PATH, ERROR_SUCCESS, result3, 20 }, + { path20, MAX_PATH, ERROR_SUCCESS, result8, 24 }, + { path21, MAX_PATH, ERROR_SUCCESS, result9, 27 }, + }; + WCHAR buf[MAX_PATH]; + DWORD i, ret, size; + + if (!pDavGetUNCFromHTTPPath) + { + win_skip( "DavGetUNCFromHTTPPath is missing\n" ); + return; + } + + if (0) { /* crash */ + ret = pDavGetUNCFromHTTPPath( NULL, NULL, NULL ); + ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); + } + ret = pDavGetUNCFromHTTPPath( path, buf, NULL ); + ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); + + size = 0; + ret = pDavGetUNCFromHTTPPath( path, NULL, &size ); + ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); + + buf[0] = 0; + size = 0; + ret = pDavGetUNCFromHTTPPath( path, buf, &size ); + ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); + + if (0) { /* crash */ + ret = pDavGetUNCFromHTTPPath( path2, buf, NULL ); + ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); + } + size = 0; + ret = pDavGetUNCFromHTTPPath( path2, NULL, &size ); + ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); + + buf[0] = 0; + size = 0; + ret = pDavGetUNCFromHTTPPath( path2, buf, &size ); + ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); + ok( size == 25, "got %u\n", size ); + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + { + buf[0] = 0; + size = tests[i].size; + ret = pDavGetUNCFromHTTPPath( tests[i].path, buf, &size ); + ok( ret == tests[i].ret, "%u: expected %u got %u\n", i, tests[i].ret, ret ); + if (tests[i].ret_path) + { + ok( !lstrcmpW( buf, tests[i].ret_path ), "%u: expected %s got %s\n", + i, wine_dbgstr_w(tests[i].ret_path), wine_dbgstr_w(buf) ); + } + ok( size == tests[i].ret_size, "%u: expected %u got %u\n", i, tests[i].ret_size, size ); + } +} + + START_TEST(access) { HMODULE hnetapi32=LoadLibraryA("netapi32.dll"); @@ -564,6 +715,7 @@ START_TEST(access) pNetLocalGroupGetInfo=(void*)GetProcAddress(hnetapi32, "NetLocalGroupGetInfo"); pNetLocalGroupGetMembers=(void*)GetProcAddress(hnetapi32, "NetLocalGroupGetMembers"); pDavGetHTTPFromUNCPath = (void*)GetProcAddress(hnetapi32, "DavGetHTTPFromUNCPath"); + pDavGetUNCFromHTTPPath = (void*)GetProcAddress(hnetapi32, "DavGetUNCFromHTTPPath"); /* These functions were introduced with NT. It's safe to assume that * if one is not available, none are. @@ -583,5 +735,6 @@ START_TEST(access) } test_DavGetHTTPFromUNCPath(); + test_DavGetUNCFromHTTPPath(); FreeLibrary(hnetapi32); } diff --git a/include/davclnt.h b/include/davclnt.h index dbb25ee..77c22e0 100644 --- a/include/davclnt.h +++ b/include/davclnt.h @@ -66,6 +66,7 @@ typedef DWORD (*PFNDAVAUTHCALLBACK) (LPWSTR,LPWSTR,DWORD,DWORD,PDAV_CALLBACK_CRED,AUTHNEXTSTEP*,PFNDAVAUTHCALLBACK_FREECRED*); DWORD WINAPI DavGetHTTPFromUNCPath(LPCWSTR,LPWSTR,LPDWORD); +DWORD WINAPI DavGetUNCFromHTTPPath(LPCWSTR,LPWSTR,LPDWORD); OPAQUE_HANDLE WINAPI DavRegisterAuthCallback(PFNDAVAUTHCALLBACK,ULONG); VOID WINAPI DavUnregisterAuthCallback(OPAQUE_HANDLE); -- 2.1.4 From hans at codeweavers.com Mon Oct 24 03:04:20 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Mon, 24 Oct 2016 10:04:20 +0200 Subject: [1/2] wbemprox: Use the WS_ prefix to avoid conflicts with Unix headers. Message-ID: <1477296261-28463-5-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/wbemprox/Makefile.in | 1 + dlls/wbemprox/builtin.c | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/dlls/wbemprox/Makefile.in b/dlls/wbemprox/Makefile.in index f411898..e6dc995 100644 --- a/dlls/wbemprox/Makefile.in +++ b/dlls/wbemprox/Makefile.in @@ -1,3 +1,4 @@ +EXTRADEFS = -DUSE_WS_PREFIX MODULE = wbemprox.dll IMPORTS = winspool version iphlpapi dxgi oleaut32 ole32 advapi32 user32 gdi32 ws2_32 rpcrt4 diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index b344a12..c8c2f4c 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -2058,11 +2058,11 @@ static enum fill_status fill_networkadapter( struct table *table, const struct e int physical; enum fill_status status = FILL_STATUS_UNFILTERED; - ret = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size ); + ret = GetAdaptersAddresses( WS_AF_UNSPEC, 0, NULL, NULL, &size ); if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED; if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED; - if (GetAdaptersAddresses( AF_UNSPEC, 0, NULL, buffer, &size )) + if (GetAdaptersAddresses( WS_AF_UNSPEC, 0, NULL, buffer, &size )) { heap_free( buffer ); return FILL_STATUS_FAILED; @@ -2111,11 +2111,11 @@ static enum fill_status fill_networkadapter( struct table *table, const struct e static WCHAR *get_dnshostname( IP_ADAPTER_UNICAST_ADDRESS *addr ) { const SOCKET_ADDRESS *sa = &addr->Address; - WCHAR buf[NI_MAXHOST]; + WCHAR buf[WS_NI_MAXHOST]; if (!addr) return NULL; if (GetNameInfoW( sa->lpSockaddr, sa->iSockaddrLength, buf, sizeof(buf)/sizeof(buf[0]), NULL, - 0, NI_NAMEREQD )) return NULL; + 0, WS_NI_NAMEREQD )) return NULL; return heap_strdupW( buf ); } static struct array *get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS *list ) @@ -2203,11 +2203,11 @@ static enum fill_status fill_networkadapterconfig( struct table *table, const st DWORD size = 0, ret; enum fill_status status = FILL_STATUS_UNFILTERED; - ret = GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, NULL, &size ); + ret = GetAdaptersAddresses( WS_AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, NULL, &size ); if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED; if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED; - if (GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, buffer, &size )) + if (GetAdaptersAddresses( WS_AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, buffer, &size )) { heap_free( buffer ); return FILL_STATUS_FAILED; -- 2.1.4 From hans at codeweavers.com Mon Oct 24 03:04:21 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Mon, 24 Oct 2016 10:04:21 +0200 Subject: [2/2] wbemprox: Return the hardware UUID for Win32_ComputerSystemProduct.UUID on macOS. Message-ID: <1477296261-28463-6-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/wbemprox/builtin.c | 51 +++++++++++++++++++++++++++++++++++++++------ dlls/wbemprox/tests/query.c | 40 +++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 6 deletions(-) diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index c8c2f4c..ee47cc7 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -22,6 +22,9 @@ #include "config.h" #include +#ifdef HAVE_UNISTD_H +# include +#endif #include "ntstatus.h" #define WIN32_NO_STATUS @@ -414,7 +417,7 @@ static const struct column col_compsys[] = static const struct column col_compsysproduct[] = { { prop_identifyingnumberW, CIM_STRING|COL_FLAG_KEY }, - { prop_uuidW, CIM_STRING } + { prop_uuidW, CIM_STRING|COL_FLAG_DYNAMIC } }; static const struct column col_datafile[] = { @@ -1055,10 +1058,6 @@ static const struct record_bios data_bios[] = { bios_descriptionW, NULL, bios_manufacturerW, bios_nameW, bios_releasedateW, bios_serialnumberW, bios_smbiosbiosversionW, bios_versionW } }; -static const struct record_computersystemproduct data_compsysproduct[] = -{ - { compsysproduct_identifyingnumberW, compsysproduct_uuidW } -}; static const struct record_param data_param[] = { { class_processW, method_getownerW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, @@ -1321,6 +1320,46 @@ static enum fill_status fill_compsys( struct table *table, const struct expr *co return status; } +static WCHAR *get_compsysproduct_uuid(void) +{ +#ifdef __APPLE__ + unsigned char uuid[16]; + const struct timespec timeout = {1, 0}; + if (!gethostuuid( uuid, &timeout )) + { + static const WCHAR fmtW[] = + {'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-', + '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X', + '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',0}; + WCHAR *ret = heap_alloc( 37 * sizeof(WCHAR) ); + if (!ret) return NULL; + sprintfW( ret, fmtW, uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], + uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15] ); + return ret; + } +#endif + return heap_strdupW( compsysproduct_uuidW ); +} + +static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond ) +{ + struct record_computersystemproduct *rec; + enum fill_status status = FILL_STATUS_UNFILTERED; + UINT row = 0; + + if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + rec = (struct record_computersystemproduct *)table->data; + rec->identifyingnumber = compsysproduct_identifyingnumberW; + rec->uuid = get_compsysproduct_uuid(); + if (!match_row( table, row, cond, &status )) free_row_values( table, row ); + else row++; + + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + struct dirstack { WCHAR **dirs; @@ -3077,7 +3116,7 @@ static struct table builtin_classes[] = { class_biosW, SIZEOF(col_bios), col_bios, SIZEOF(data_bios), 0, (BYTE *)data_bios }, { class_cdromdriveW, SIZEOF(col_cdromdrive), col_cdromdrive, 0, 0, NULL, fill_cdromdrive }, { class_compsysW, SIZEOF(col_compsys), col_compsys, 0, 0, NULL, fill_compsys }, - { class_compsysproductW, SIZEOF(col_compsysproduct), col_compsysproduct, SIZEOF(data_compsysproduct), 0, (BYTE *)data_compsysproduct }, + { class_compsysproductW, SIZEOF(col_compsysproduct), col_compsysproduct, 0, 0, NULL, fill_compsysproduct }, { class_datafileW, SIZEOF(col_datafile), col_datafile, 0, 0, NULL, fill_datafile }, { class_desktopmonitorW, SIZEOF(col_desktopmonitor), col_desktopmonitor, 0, 0, NULL, fill_desktopmonitor }, { class_directoryW, SIZEOF(col_directory), col_directory, 0, 0, NULL, fill_directory }, diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c index d41aa11..2513807 100644 --- a/dlls/wbemprox/tests/query.c +++ b/dlls/wbemprox/tests/query.c @@ -1176,6 +1176,45 @@ static void test_OperatingSystem( IWbemServices *services ) SysFreeString( wql ); } +static void test_ComputerSystemProduct( IWbemServices *services ) +{ + static const WCHAR uuidW[] = {'U','U','I','D',0}; + static const WCHAR queryW[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_', + 'C','o','m','p','u','t','e','r','S','y','s','t','e','m','P','r','o','d','u','c','t',0}; + BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW ); + IEnumWbemClassObject *result; + IWbemClassObject *service; + VARIANT value; + CIMTYPE type; + HRESULT hr; + DWORD count; + + hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result ); + if (hr != S_OK) + { + win_skip( "Win32_ComputerSystemProduct not available\n" ); + return; + } + + hr = IEnumWbemClassObject_Next( result, 10000, 1, &service, &count ); + ok( hr == S_OK, "got %08x\n", hr ); + + type = 0xdeadbeef; + VariantInit( &value ); + hr = IWbemClassObject_Get( service, uuidW, 0, &value, &type, NULL ); + ok( hr == S_OK, "failed to get computer name %08x\n", hr ); + ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) ); + ok( type == CIM_STRING, "unexpected type 0x%x\n", type ); + trace( "uuid %s\n", wine_dbgstr_w(V_BSTR(&value)) ); + VariantClear( &value ); + + IWbemClassObject_Release( service ); + IEnumWbemClassObject_Release( result ); + SysFreeString( query ); + SysFreeString( wql ); +} + START_TEST(query) { static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0}; @@ -1214,6 +1253,7 @@ START_TEST(query) test_GetNames( services ); test_SystemSecurity( services ); test_OperatingSystem( services ); + test_ComputerSystemProduct( services ); SysFreeString( path ); IWbemServices_Release( services ); -- 2.1.4 From huw at codeweavers.com Mon Oct 24 04:15:18 2016 From: huw at codeweavers.com (Huw Davies) Date: Mon, 24 Oct 2016 10:15:18 +0100 Subject: winemac: Update the keyboard layout data immediately after changing the input source. Message-ID: <1477300518-37075-1-git-send-email-huw@codeweavers.com> It would eventually get updated by the keyboard changed event, but only after the message queue was pumped. Signed-off-by: Huw Davies --- dlls/winemac.drv/cocoa_app.m | 3 ++- dlls/winemac.drv/keyboard.c | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m index dced704..0eaea57 100644 --- a/dlls/winemac.drv/cocoa_app.m +++ b/dlls/winemac.drv/cocoa_app.m @@ -2426,7 +2426,8 @@ void macdrv_get_input_source_info(CFDataRef* uchr, CGEventSourceKeyboardType* ke *keyboard_type = [WineApplicationController sharedController].keyboardType; *is_iso = (KBGetLayoutType(*keyboard_type) == kKeyboardISO); - *input_source = TISCopyCurrentKeyboardInputSource(); + if (input_source) + *input_source = TISCopyCurrentKeyboardInputSource(); } }); } diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c index 6680e6b..3e0ebbf 100644 --- a/dlls/winemac.drv/keyboard.c +++ b/dlls/winemac.drv/keyboard.c @@ -1186,7 +1186,15 @@ HKL CDECL macdrv_ActivateKeyboardLayout(HKL hkl, UINT flags) if (macdrv_select_input_source(layout->input_source)) { oldHkl = thread_data->active_keyboard_layout; + if (thread_data->keyboard_layout_uchr) + CFRelease(thread_data->keyboard_layout_uchr); + + macdrv_get_input_source_info(&thread_data->keyboard_layout_uchr, &thread_data->keyboard_type, + &thread_data->iso_keyboard, NULL); thread_data->active_keyboard_layout = hkl; + thread_data->dead_key_state = 0; + + macdrv_compute_keyboard_layout(thread_data); } break; } -- 2.8.2 From jkucia at codeweavers.com Mon Oct 24 04:57:24 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 24 Oct 2016 11:57:24 +0200 Subject: [PATCH v2 1/5] wined3d: Replace wined3d_buffer_load_sysmem() calls with wined3d_buffer_load_location(). Message-ID: <1477303048-7961-1-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- Version 2: * Do not reset WINED3D_BUFFER_DOUBLEBUFFER unconditionally. * Replace wined3d_buffer_load_sysmem() only in the buffer.c file. --- dlls/wined3d/buffer.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index eae55e1..d8b47fc 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -631,6 +631,7 @@ void wined3d_buffer_get_memory(struct wined3d_buffer *buffer, static void buffer_unload(struct wined3d_resource *resource) { struct wined3d_buffer *buffer = buffer_from_resource(resource); + DWORD flags = buffer->flags; TRACE("buffer %p.\n", buffer); @@ -641,12 +642,10 @@ static void buffer_unload(struct wined3d_resource *resource) context = context_acquire(device, NULL); - /* Download the buffer, but don't permanently enable double buffering */ - if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) - { - wined3d_buffer_load_sysmem(buffer, context); + /* Download the buffer, but don't permanently enable double buffering. */ + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); + if (!(flags & WINED3D_BUFFER_DOUBLEBUFFER)) buffer->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER; - } wined3d_buffer_invalidate_location(buffer, WINED3D_LOCATION_BUFFER); delete_gl_buffer(buffer, context->gl_info); @@ -988,8 +987,7 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context * if (buffer->buffer_type_hint != GL_ARRAY_BUFFER) ERR("Converting data in non-vertex buffer.\n"); - if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) - wined3d_buffer_load_sysmem(buffer, context); + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); /* Now for each vertex in the buffer that needs conversion */ vertex_count = buffer->resource.size / buffer->stride; @@ -1144,7 +1142,7 @@ static HRESULT wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UI else { TRACE("Falling back to doublebuffered operation.\n"); - wined3d_buffer_load_sysmem(buffer, context); + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); } TRACE("New pointer is %p.\n", buffer->resource.heap_memory); buffer->map_ptr = NULL; -- 2.7.3 From jkucia at codeweavers.com Mon Oct 24 04:57:25 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 24 Oct 2016 11:57:25 +0200 Subject: [PATCH resend 2/5] wined3d: Introduce buffer_conversion_upload() helper function. In-Reply-To: <1477303048-7961-1-git-send-email-jkucia@codeweavers.com> References: <1477303048-7961-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1477303048-7961-2-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 122 +++++++++++++++++++++++++++----------------------- 1 file changed, 65 insertions(+), 57 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index d8b47fc..e0e62c5 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -852,6 +852,69 @@ static void buffer_direct_upload(struct wined3d_buffer *This, struct wined3d_con wined3d_buffer_validate_location(This, WINED3D_LOCATION_BUFFER); } +static void buffer_conversion_upload(struct wined3d_buffer *buffer, struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int i, j, start, end, len, vertex_count; + BYTE *data; + + /* This would potentially invalidate the element array buffer binding. */ + if (buffer->buffer_type_hint != GL_ARRAY_BUFFER) + ERR("Converting data in non-vertex buffer.\n"); + + wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); + + /* Now for each vertex in the buffer that needs conversion. */ + vertex_count = buffer->resource.size / buffer->stride; + + if (!(data = HeapAlloc(GetProcessHeap(), 0, buffer->resource.size))) + { + ERR("Out of memory.\n"); + return; + } + + while (buffer->modified_areas) + { + buffer->modified_areas--; + start = buffer->maps[buffer->modified_areas].offset; + len = buffer->maps[buffer->modified_areas].size; + end = start + len; + + memcpy(data + start, (BYTE *)buffer->resource.heap_memory + start, end - start); + for (i = start / buffer->stride; i < min((end / buffer->stride) + 1, vertex_count); ++i) + { + for (j = 0; j < buffer->stride;) + { + switch (buffer->conversion_map[j]) + { + case CONV_NONE: + /* Done already */ + j += sizeof(DWORD); + break; + case CONV_D3DCOLOR: + j += fixup_d3dcolor((DWORD *) (data + i * buffer->stride + j)); + break; + case CONV_POSITIONT: + j += fixup_transformed_pos((float *) (data + i * buffer->stride + j)); + break; + default: + FIXME("Unimplemented conversion %d in shifted conversion.\n", buffer->conversion_map[j]); + ++j; + } + } + } + + GL_EXTCALL(glBindBuffer(buffer->buffer_type_hint, buffer->buffer_object)); + checkGLcall("glBindBuffer"); + GL_EXTCALL(glBufferSubData(buffer->buffer_type_hint, start, len, data + start)); + checkGLcall("glBufferSubData"); + } + + HeapFree(GetProcessHeap(), 0, data); + + wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_BUFFER); +} + void buffer_mark_used(struct wined3d_buffer *buffer) { buffer->flags &= ~(WINED3D_BUFFER_SYNC | WINED3D_BUFFER_DISCARD); @@ -863,9 +926,7 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context * { DWORD flags = buffer->flags & (WINED3D_BUFFER_SYNC | WINED3D_BUFFER_DISCARD); const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int i, j, start, end, len, vertex_count; BOOL decl_changed = FALSE; - BYTE *data; TRACE("buffer %p.\n", buffer); @@ -980,64 +1041,11 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context * return; buffer_direct_upload(buffer, context, flags); - return; } - - /* This would potentially invalidate the element array buffer binding. */ - if (buffer->buffer_type_hint != GL_ARRAY_BUFFER) - ERR("Converting data in non-vertex buffer.\n"); - - wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); - - /* Now for each vertex in the buffer that needs conversion */ - vertex_count = buffer->resource.size / buffer->stride; - - if (!(data = HeapAlloc(GetProcessHeap(), 0, buffer->resource.size))) + else { - ERR("Out of memory.\n"); - return; + buffer_conversion_upload(buffer, context); } - - while (buffer->modified_areas) - { - buffer->modified_areas--; - start = buffer->maps[buffer->modified_areas].offset; - len = buffer->maps[buffer->modified_areas].size; - end = start + len; - - memcpy(data + start, (BYTE *)buffer->resource.heap_memory + start, end - start); - for (i = start / buffer->stride; i < min((end / buffer->stride) + 1, vertex_count); ++i) - { - for (j = 0; j < buffer->stride;) - { - switch (buffer->conversion_map[j]) - { - case CONV_NONE: - /* Done already */ - j += sizeof(DWORD); - break; - case CONV_D3DCOLOR: - j += fixup_d3dcolor((DWORD *) (data + i * buffer->stride + j)); - break; - case CONV_POSITIONT: - j += fixup_transformed_pos((float *) (data + i * buffer->stride + j)); - break; - default: - FIXME("Unimplemented conversion %d in shifted conversion.\n", buffer->conversion_map[j]); - ++j; - } - } - } - - GL_EXTCALL(glBindBuffer(buffer->buffer_type_hint, buffer->buffer_object)); - checkGLcall("glBindBuffer"); - GL_EXTCALL(glBufferSubData(buffer->buffer_type_hint, start, len, data + start)); - checkGLcall("glBufferSubData"); - } - - HeapFree(GetProcessHeap(), 0, data); - - wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_BUFFER); } struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffer *buffer) -- 2.7.3 From jkucia at codeweavers.com Mon Oct 24 04:57:26 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 24 Oct 2016 11:57:26 +0200 Subject: [PATCH 3/5] wined3d: Simplify remove_vbos(). In-Reply-To: <1477303048-7961-1-git-send-email-jkucia@codeweavers.com> References: <1477303048-7961-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1477303048-7961-3-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/drawprim.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 4833845..bf035ae 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -391,18 +391,19 @@ static void remove_vbos(struct wined3d_context *context, { unsigned int i; - for (i = 0; i < (sizeof(s->elements) / sizeof(*s->elements)); ++i) + for (i = 0; i < ARRAY_SIZE(s->elements); ++i) { struct wined3d_stream_info_element *e; - if (!(s->use_map & (1u << i))) continue; + if (!(s->use_map & (1u << i))) + continue; e = &s->elements[i]; if (e->data.buffer_object) { struct wined3d_buffer *vb = state->streams[e->stream_idx].buffer; e->data.buffer_object = 0; - e->data.addr = (BYTE *)((ULONG_PTR)e->data.addr + (ULONG_PTR)wined3d_buffer_load_sysmem(vb, context)); + e->data.addr += (ULONG_PTR)wined3d_buffer_load_sysmem(vb, context); } } } -- 2.7.3 From jkucia at codeweavers.com Mon Oct 24 04:57:27 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 24 Oct 2016 11:57:27 +0200 Subject: [PATCH 4/5] wined3d: Fix index offset for immediate mode draws. In-Reply-To: <1477303048-7961-1-git-send-email-jkucia@codeweavers.com> References: <1477303048-7961-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1477303048-7961-4-git-send-email-jkucia@codeweavers.com> This fixes 42fcf202211f62ccec21863b36076c2d5e02c1da. A non-NULL pointer doesn't imply that the pointer isn't an offset into a buffer object data. Signed-off-by: Józef Kucia --- dlls/wined3d/drawprim.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index bf035ae..36c8d98 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -196,12 +196,10 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const if (instance_count) FIXME("Instancing not implemented.\n"); - /* Immediate mode drawing can't make use of indices in a vbo - get the - * data from the index buffer. If the index buffer has no vbo (not - * supported or other reason), or with user pointer drawing idx_data - * will be non-NULL. */ - if (idx_size && !idx_data) - idx_data = wined3d_buffer_load_sysmem(state->index_buffer, context); + /* Immediate mode drawing can't make use of indices in a VBO - get the + * data from the index buffer. */ + if (idx_size) + idx_data = wined3d_buffer_load_sysmem(state->index_buffer, context) + state->index_offset; ops = &d3d_info->ffp_attrib_ops; -- 2.7.3 From jkucia at codeweavers.com Mon Oct 24 04:57:28 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 24 Oct 2016 11:57:28 +0200 Subject: [PATCH 5/5] wined3d: Use buffer_bind() in buffer_conversion_upload(). In-Reply-To: <1477303048-7961-1-git-send-email-jkucia@codeweavers.com> References: <1477303048-7961-1-git-send-email-jkucia@codeweavers.com> Message-ID: <1477303048-7961-5-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index e0e62c5..a81cd64 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -858,10 +858,6 @@ static void buffer_conversion_upload(struct wined3d_buffer *buffer, struct wined unsigned int i, j, start, end, len, vertex_count; BYTE *data; - /* This would potentially invalidate the element array buffer binding. */ - if (buffer->buffer_type_hint != GL_ARRAY_BUFFER) - ERR("Converting data in non-vertex buffer.\n"); - wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM); /* Now for each vertex in the buffer that needs conversion. */ @@ -873,6 +869,7 @@ static void buffer_conversion_upload(struct wined3d_buffer *buffer, struct wined return; } + buffer_bind(buffer, context); while (buffer->modified_areas) { buffer->modified_areas--; @@ -904,8 +901,6 @@ static void buffer_conversion_upload(struct wined3d_buffer *buffer, struct wined } } - GL_EXTCALL(glBindBuffer(buffer->buffer_type_hint, buffer->buffer_object)); - checkGLcall("glBindBuffer"); GL_EXTCALL(glBufferSubData(buffer->buffer_type_hint, start, len, data + start)); checkGLcall("glBufferSubData"); } -- 2.7.3 From hverbeet at codeweavers.com Mon Oct 24 06:06:46 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 24 Oct 2016 13:06:46 +0200 Subject: [PATCH resend 2/5] wined3d: Introduce buffer_conversion_upload() helper function. In-Reply-To: <1477303048-7961-2-git-send-email-jkucia@codeweavers.com> References: <1477303048-7961-2-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 24 06:06:47 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 24 Oct 2016 13:06:47 +0200 Subject: [PATCH 3/5] wined3d: Simplify remove_vbos(). In-Reply-To: <1477303048-7961-3-git-send-email-jkucia@codeweavers.com> References: <1477303048-7961-3-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 24 06:06:52 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 24 Oct 2016 13:06:52 +0200 Subject: [PATCH 4/5] wined3d: Fix index offset for immediate mode draws. In-Reply-To: <1477303048-7961-4-git-send-email-jkucia@codeweavers.com> References: <1477303048-7961-4-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 24 06:06:54 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 24 Oct 2016 13:06:54 +0200 Subject: [PATCH 5/5] wined3d: Use buffer_bind() in buffer_conversion_upload(). In-Reply-To: <1477303048-7961-5-git-send-email-jkucia@codeweavers.com> References: <1477303048-7961-5-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 24 06:06:44 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 24 Oct 2016 13:06:44 +0200 Subject: [PATCH v2 1/5] wined3d: Replace wined3d_buffer_load_sysmem() calls with wined3d_buffer_load_location(). In-Reply-To: <1477303048-7961-1-git-send-email-jkucia@codeweavers.com> References: <1477303048-7961-1-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hugh.mcmaster at outlook.com Mon Oct 24 06:26:58 2016 From: hugh.mcmaster at outlook.com (Hugh McMaster) Date: Mon, 24 Oct 2016 11:26:58 +0000 Subject: [PATCH 1/4] regedit/tests: Replace the hard-coded subkey path with a define Message-ID: Signed-off-by: Hugh McMaster --- programs/regedit/tests/regedit.c | 86 +++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 50 deletions(-) diff --git a/programs/regedit/tests/regedit.c b/programs/regedit/tests/regedit.c index 2002e64..cc6cf43 100644 --- a/programs/regedit/tests/regedit.c +++ b/programs/regedit/tests/regedit.c @@ -241,6 +241,8 @@ static void r_verify_reg_nonexist(unsigned line, HKEY key, const char *subkey, value_name); } +#define KEY_BASE "Software\\Wine\\regedit_test" + static void test_basic_import(void) { char exp_binary[] = {0xAA,0xBB,0xCC,0x11}; @@ -263,58 +265,51 @@ static void test_basic_import(void) WCHAR wide_exp[] = {0x3041,'V','a','l','u','e',0}; LONG lr; - lr = RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test"); + lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr); exec_import_str("REGEDIT4\n\n" - "[HKEY_CURRENT_USER\\Software\\Wine\\regedit_test]\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"TestValue\"=\"AValue\"\n"); - verify_reg_sz(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "TestValue", "AValue"); + verify_reg_sz(HKEY_CURRENT_USER, KEY_BASE, "TestValue", "AValue"); exec_import_str("REGEDIT4\r\n\r\n" - "[HKEY_CURRENT_USER\\Software\\Wine\\regedit_test]\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\r\n" "\"TestValue2\"=\"BValue\"\r\n"); - verify_reg_sz(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "TestValue2", "BValue"); + verify_reg_sz(HKEY_CURRENT_USER, KEY_BASE, "TestValue2", "BValue"); if(supports_wchar){ exec_import_wstr(wide_test); - verify_reg_wsz(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "TestValue3", wide_exp); + verify_reg_wsz(HKEY_CURRENT_USER, KEY_BASE, "TestValue3", wide_exp); exec_import_wstr(wide_test_r); - verify_reg_wsz(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "TestValue5", wide_exp); + verify_reg_wsz(HKEY_CURRENT_USER, KEY_BASE, "TestValue5", wide_exp); }else win_skip("Some WCHAR tests skipped\n"); exec_import_str("REGEDIT4\r\r" - "[HKEY_CURRENT_USER\\Software\\Wine\\regedit_test]\r" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\r" "\"TestValue4\"=\"DValue\"\r"); - verify_reg_sz(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "TestValue4", "DValue"); + verify_reg_sz(HKEY_CURRENT_USER, KEY_BASE, "TestValue4", "DValue"); exec_import_str("REGEDIT4\n\n" - "[HKEY_CURRENT_USER\\Software\\Wine\\regedit_test]\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"TestDword\"=dword:00000017\n"); - verify_reg_dword(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "TestDword", 0x17); + verify_reg_dword(HKEY_CURRENT_USER, KEY_BASE, "TestDword", 0x17); exec_import_str("REGEDIT4\n\n" - "[HKEY_CURRENT_USER\\Software\\Wine\\regedit_test]\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"TestBinary\"=hex:aa,bb,cc,11\n"); - verify_reg_binary(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", + verify_reg_binary(HKEY_CURRENT_USER, KEY_BASE, "TestBinary", exp_binary, sizeof(exp_binary)); exec_import_str("REGEDIT4\n\n" - "[HKEY_CURRENT_USER\\Software\\Wine\\regedit_test]\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"With=Equals\"=\"asdf\"\n"); - verify_reg_sz(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "With=Equals", "asdf"); + verify_reg_sz(HKEY_CURRENT_USER, KEY_BASE, "With=Equals", "asdf"); - lr = RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test"); + lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); ok(lr == ERROR_SUCCESS, "RegDeleteKeyA failed: %d\n", lr); } @@ -322,55 +317,46 @@ static void test_invalid_import(void) { LONG lr; - lr = RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test"); - ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, - "RegDeleteKeyA failed: %d\n", lr); + lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); + ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr); exec_import_str("REGEDIT4\n\n" - "[HKEY_CURRENT_USER\\Software\\Wine\\regedit_test]\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"TestNoEndQuote\"=\"Asdffdsa\n"); - verify_reg_nonexist(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "TestNoEndQuote"); + verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "TestNoEndQuote"); exec_import_str("REGEDIT4\n\n" - "[HKEY_CURRENT_USER\\Software\\Wine\\regedit_test]\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"TestNoBeginQuote\"=Asdffdsa\"\n"); - verify_reg_nonexist(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "TestNoBeginQuote"); + verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "TestNoBeginQuote"); exec_import_str("REGEDIT4\n\n" - "[HKEY_CURRENT_USER\\Software\\Wine\\regedit_test]\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"TestNoQuotes\"=Asdffdsa\n"); - verify_reg_nonexist(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "TestNoQuotes"); + verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "TestNoQuotes"); exec_import_str("REGEDIT4\n\n" - "[HKEY_CURRENT_USER\\Software\\Wine\\regedit_test]\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"NameNoEndQuote=\"Asdffdsa\"\n"); - verify_reg_nonexist(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "NameNoEndQuote"); + verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "NameNoEndQuote"); exec_import_str("REGEDIT4\n\n" - "[HKEY_CURRENT_USER\\Software\\Wine\\regedit_test]\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "NameNoBeginQuote\"=\"Asdffdsa\"\n"); - verify_reg_nonexist(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "NameNoBeginQuote"); + verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "NameNoBeginQuote"); exec_import_str("REGEDIT4\n\n" - "[HKEY_CURRENT_USER\\Software\\Wine\\regedit_test]\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "NameNoQuotes=\"Asdffdsa\"\n"); - verify_reg_nonexist(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "NameNoQuotes"); + verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "NameNoQuotes"); exec_import_str("REGEDIT4\n\n" - "[HKEY_CURRENT_USER\\Software\\Wine\\regedit_test]\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"MixedQuotes=Asdffdsa\"\n"); - verify_reg_nonexist(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "MixedQuotes"); - verify_reg_nonexist(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test", - "MixedQuotes=Asdffdsa"); + verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "MixedQuotes"); + verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "MixedQuotes=Asdffdsa"); - lr = RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Wine\\regedit_test"); + lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); ok(lr == ERROR_SUCCESS, "RegDeleteKeyA failed: %d\n", lr); } -- 2.7.4 From hugh.mcmaster at outlook.com Mon Oct 24 06:27:14 2016 From: hugh.mcmaster at outlook.com (Hugh McMaster) Date: Mon, 24 Oct 2016 11:27:14 +0000 Subject: [PATCH 2/4] regedit/tests: Open the registry key once in each test function In-Reply-To: <1477308397-6931-1-git-send-email-hugh.mcmaster@outlook.com> References: <1477308397-6931-1-git-send-email-hugh.mcmaster@outlook.com> Message-ID: Signed-off-by: Hugh McMaster --- programs/regedit/tests/regedit.c | 123 ++++++++++++++------------------------- 1 file changed, 45 insertions(+), 78 deletions(-) diff --git a/programs/regedit/tests/regedit.c b/programs/regedit/tests/regedit.c index cc6cf43..db4ccd8 100644 --- a/programs/regedit/tests/regedit.c +++ b/programs/regedit/tests/regedit.c @@ -98,24 +98,15 @@ static BOOL r_exec_import_wstr(unsigned line, const WCHAR *file_contents) return (dr != WAIT_TIMEOUT); } -#define verify_reg_sz(k,s,n,e) r_verify_reg_sz(__LINE__,k,s,n,e) -static void r_verify_reg_sz(unsigned line, HKEY key, const char *subkey, - const char *value_name, const char *exp_value) +#define verify_reg_sz(k,n,e) r_verify_reg_sz(__LINE__,k,n,e) +static void r_verify_reg_sz(unsigned line, HKEY key, const char *value_name, const char *exp_value) { LONG lr; DWORD fnd_type, fnd_len; char fnd_value[1024]; - HKEY fnd_key; - - lr = RegOpenKeyExA(key, subkey, 0, KEY_READ, &fnd_key); - lok(lr == ERROR_SUCCESS, "RegOpenKeyExA failed: %d\n", lr); - if(lr != ERROR_SUCCESS) - return; fnd_len = sizeof(fnd_value); - lr = RegQueryValueExA(fnd_key, value_name, NULL, &fnd_type, - (BYTE*)fnd_value, &fnd_len); - RegCloseKey(fnd_key); + lr = RegQueryValueExA(key, value_name, NULL, &fnd_type, (BYTE*)fnd_value, &fnd_len); lok(lr == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", lr); if(lr != ERROR_SUCCESS) return; @@ -127,27 +118,18 @@ static void r_verify_reg_sz(unsigned line, HKEY key, const char *subkey, "Strings differ: expected %s, got %s\n", exp_value, fnd_value); } -#define verify_reg_wsz(k,s,n,e) r_verify_reg_wsz(__LINE__,k,s,n,e) -static void r_verify_reg_wsz(unsigned line, HKEY key, const char *subkey, - const char *value_name, const WCHAR *exp_value) +#define verify_reg_wsz(k,n,e) r_verify_reg_wsz(__LINE__,k,n,e) +static void r_verify_reg_wsz(unsigned line, HKEY key, const char *value_name, const WCHAR *exp_value) { LONG lr; DWORD fnd_type, fnd_len; WCHAR fnd_value[1024], value_nameW[1024]; - HKEY fnd_key; - - lr = RegOpenKeyExA(key, subkey, 0, KEY_READ, &fnd_key); - lok(lr == ERROR_SUCCESS, "RegOpenKeyExA failed: %d\n", lr); - if(lr != ERROR_SUCCESS) - return; MultiByteToWideChar(CP_ACP, 0, value_name, -1, value_nameW, sizeof(value_nameW)/sizeof(value_nameW[0])); fnd_len = sizeof(fnd_value); - lr = RegQueryValueExW(fnd_key, value_nameW, NULL, &fnd_type, - (BYTE*)fnd_value, &fnd_len); - RegCloseKey(fnd_key); + lr = RegQueryValueExW(key, value_nameW, NULL, &fnd_type, (BYTE*)fnd_value, &fnd_len); lok(lr == ERROR_SUCCESS, "RegQueryValueExW failed: %d\n", lr); if(lr != ERROR_SUCCESS) return; @@ -160,23 +142,14 @@ static void r_verify_reg_wsz(unsigned line, HKEY key, const char *subkey, wine_dbgstr_w(exp_value), wine_dbgstr_w(fnd_value)); } -#define verify_reg_dword(k,s,n,e) r_verify_reg_dword(__LINE__,k,s,n,e) -static void r_verify_reg_dword(unsigned line, HKEY key, const char *subkey, - const char *value_name, DWORD exp_value) +#define verify_reg_dword(k,n,e) r_verify_reg_dword(__LINE__,k,n,e) +static void r_verify_reg_dword(unsigned line, HKEY key, const char *value_name, DWORD exp_value) { LONG lr; DWORD fnd_type, fnd_len, fnd_value; - HKEY fnd_key; - - lr = RegOpenKeyExA(key, subkey, 0, KEY_READ, &fnd_key); - lok(lr == ERROR_SUCCESS, "RegOpenKeyExA failed: %d\n", lr); - if(lr != ERROR_SUCCESS) - return; fnd_len = sizeof(fnd_value); - lr = RegQueryValueExA(fnd_key, value_name, NULL, &fnd_type, - (BYTE *)&fnd_value, &fnd_len); - RegCloseKey(fnd_key); + lr = RegQueryValueExA(key, value_name, NULL, &fnd_type, (BYTE *)&fnd_value, &fnd_len); lok(lr == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", lr); if(lr != ERROR_SUCCESS) return; @@ -188,24 +161,16 @@ static void r_verify_reg_dword(unsigned line, HKEY key, const char *subkey, exp_value, fnd_value); } -#define verify_reg_binary(k,s,n,e,z) r_verify_reg_binary(__LINE__,k,s,n,e,z) -static void r_verify_reg_binary(unsigned line, HKEY key, const char *subkey, +#define verify_reg_binary(k,n,e,z) r_verify_reg_binary(__LINE__,k,n,e,z) +static void r_verify_reg_binary(unsigned line, HKEY key, const char *value_name, const char *exp_value, int exp_len) { LONG lr; DWORD fnd_type, fnd_len; char fnd_value[1024]; - HKEY fnd_key; - - lr = RegOpenKeyExA(key, subkey, 0, KEY_READ, &fnd_key); - lok(lr == ERROR_SUCCESS, "RegOpenKeyExA failed: %d\n", lr); - if(lr != ERROR_SUCCESS) - return; fnd_len = sizeof(fnd_value); - lr = RegQueryValueExA(fnd_key, value_name, NULL, &fnd_type, - (BYTE*)fnd_value, &fnd_len); - RegCloseKey(fnd_key); + lr = RegQueryValueExA(key, value_name, NULL, &fnd_type, (BYTE*)fnd_value, &fnd_len); lok(lr == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", lr); if(lr != ERROR_SUCCESS) return; @@ -219,24 +184,15 @@ static void r_verify_reg_binary(unsigned line, HKEY key, const char *subkey, "Data differs\n"); } -#define verify_reg_nonexist(k,s,n) r_verify_reg_nonexist(__LINE__,k,s,n) -static void r_verify_reg_nonexist(unsigned line, HKEY key, const char *subkey, - const char *value_name) +#define verify_reg_nonexist(k,n) r_verify_reg_nonexist(__LINE__,k,n) +static void r_verify_reg_nonexist(unsigned line, HKEY key, const char *value_name) { LONG lr; DWORD fnd_type, fnd_len; char fnd_value[32]; - HKEY fnd_key; - - lr = RegOpenKeyExA(key, subkey, 0, KEY_READ, &fnd_key); - lok(lr == ERROR_SUCCESS, "RegOpenKeyExA failed: %d\n", lr); - if(lr != ERROR_SUCCESS) - return; fnd_len = sizeof(fnd_value); - lr = RegQueryValueExA(fnd_key, value_name, NULL, &fnd_type, - (BYTE*)fnd_value, &fnd_len); - RegCloseKey(fnd_key); + lr = RegQueryValueExA(key, value_name, NULL, &fnd_type, (BYTE*)fnd_value, &fnd_len); lok(lr == ERROR_FILE_NOT_FOUND, "Reg value shouldn't exist: %s\n", value_name); } @@ -245,6 +201,7 @@ static void r_verify_reg_nonexist(unsigned line, HKEY key, const char *subkey, static void test_basic_import(void) { + HKEY hkey; char exp_binary[] = {0xAA,0xBB,0xCC,0x11}; WCHAR wide_test[] = {0xFEFF,'W','i','n','d','o','w','s',' ','R','e','g', 'i','s','t','r','y',' ','E','d','i','t','o','r',' ','V','e','r','s', @@ -272,42 +229,47 @@ static void test_basic_import(void) exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"TestValue\"=\"AValue\"\n"); - verify_reg_sz(HKEY_CURRENT_USER, KEY_BASE, "TestValue", "AValue"); + lr = RegOpenKeyExA(HKEY_CURRENT_USER, KEY_BASE, 0, KEY_READ, &hkey); + ok(lr == ERROR_SUCCESS, "RegOpenKeyExA failed: %d\n", lr); + verify_reg_sz(hkey, "TestValue", "AValue"); exec_import_str("REGEDIT4\r\n\r\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\r\n" "\"TestValue2\"=\"BValue\"\r\n"); - verify_reg_sz(HKEY_CURRENT_USER, KEY_BASE, "TestValue2", "BValue"); + verify_reg_sz(hkey, "TestValue2", "BValue"); - if(supports_wchar){ + if (supports_wchar) + { exec_import_wstr(wide_test); - verify_reg_wsz(HKEY_CURRENT_USER, KEY_BASE, "TestValue3", wide_exp); + verify_reg_wsz(hkey, "TestValue3", wide_exp); exec_import_wstr(wide_test_r); - verify_reg_wsz(HKEY_CURRENT_USER, KEY_BASE, "TestValue5", wide_exp); - }else + verify_reg_wsz(hkey, "TestValue5", wide_exp); + } + else win_skip("Some WCHAR tests skipped\n"); exec_import_str("REGEDIT4\r\r" "[HKEY_CURRENT_USER\\" KEY_BASE "]\r" "\"TestValue4\"=\"DValue\"\r"); - verify_reg_sz(HKEY_CURRENT_USER, KEY_BASE, "TestValue4", "DValue"); + verify_reg_sz(hkey, "TestValue4", "DValue"); exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"TestDword\"=dword:00000017\n"); - verify_reg_dword(HKEY_CURRENT_USER, KEY_BASE, "TestDword", 0x17); + verify_reg_dword(hkey, "TestDword", 0x17); exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"TestBinary\"=hex:aa,bb,cc,11\n"); - verify_reg_binary(HKEY_CURRENT_USER, KEY_BASE, - "TestBinary", exp_binary, sizeof(exp_binary)); + verify_reg_binary(hkey, "TestBinary", exp_binary, sizeof(exp_binary)); exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"With=Equals\"=\"asdf\"\n"); - verify_reg_sz(HKEY_CURRENT_USER, KEY_BASE, "With=Equals", "asdf"); + verify_reg_sz(hkey, "With=Equals", "asdf"); + + RegCloseKey(hkey); lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); ok(lr == ERROR_SUCCESS, "RegDeleteKeyA failed: %d\n", lr); @@ -316,6 +278,7 @@ static void test_basic_import(void) static void test_invalid_import(void) { LONG lr; + HKEY hkey; lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr); @@ -323,38 +286,42 @@ static void test_invalid_import(void) exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"TestNoEndQuote\"=\"Asdffdsa\n"); - verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "TestNoEndQuote"); + lr = RegOpenKeyExA(HKEY_CURRENT_USER, KEY_BASE, 0, KEY_READ, &hkey); + ok(lr == ERROR_SUCCESS, "RegOpenKeyExA failed: %d\n", lr); + verify_reg_nonexist(hkey, "TestNoEndQuote"); exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"TestNoBeginQuote\"=Asdffdsa\"\n"); - verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "TestNoBeginQuote"); + verify_reg_nonexist(hkey, "TestNoBeginQuote"); exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"TestNoQuotes\"=Asdffdsa\n"); - verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "TestNoQuotes"); + verify_reg_nonexist(hkey, "TestNoQuotes"); exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"NameNoEndQuote=\"Asdffdsa\"\n"); - verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "NameNoEndQuote"); + verify_reg_nonexist(hkey, "NameNoEndQuote"); exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "NameNoBeginQuote\"=\"Asdffdsa\"\n"); - verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "NameNoBeginQuote"); + verify_reg_nonexist(hkey, "NameNoBeginQuote"); exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "NameNoQuotes=\"Asdffdsa\"\n"); - verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "NameNoQuotes"); + verify_reg_nonexist(hkey, "NameNoQuotes"); exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"MixedQuotes=Asdffdsa\"\n"); - verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "MixedQuotes"); - verify_reg_nonexist(HKEY_CURRENT_USER, KEY_BASE, "MixedQuotes=Asdffdsa"); + verify_reg_nonexist(hkey, "MixedQuotes"); + verify_reg_nonexist(hkey, "MixedQuotes=Asdffdsa"); + + RegCloseKey(hkey); lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); ok(lr == ERROR_SUCCESS, "RegDeleteKeyA failed: %d\n", lr); -- 2.7.4 From hugh.mcmaster at outlook.com Mon Oct 24 06:27:25 2016 From: hugh.mcmaster at outlook.com (Hugh McMaster) Date: Mon, 24 Oct 2016 11:27:25 +0000 Subject: [PATCH 3/4] regedit/tests: Handle different data types with one verify_reg() function In-Reply-To: <1477308397-6931-1-git-send-email-hugh.mcmaster@outlook.com> References: <1477308397-6931-1-git-send-email-hugh.mcmaster@outlook.com> Message-ID: Signed-off-by: Hugh McMaster --- programs/regedit/tests/regedit.c | 93 +++++++++++++--------------------------- 1 file changed, 30 insertions(+), 63 deletions(-) diff --git a/programs/regedit/tests/regedit.c b/programs/regedit/tests/regedit.c index db4ccd8..eeff9d8 100644 --- a/programs/regedit/tests/regedit.c +++ b/programs/regedit/tests/regedit.c @@ -98,24 +98,32 @@ static BOOL r_exec_import_wstr(unsigned line, const WCHAR *file_contents) return (dr != WAIT_TIMEOUT); } -#define verify_reg_sz(k,n,e) r_verify_reg_sz(__LINE__,k,n,e) -static void r_verify_reg_sz(unsigned line, HKEY key, const char *value_name, const char *exp_value) +#define TODO_REG_TYPE (0x0001u) +#define TODO_REG_SIZE (0x0002u) +#define TODO_REG_DATA (0x0004u) + +/* verify_reg() adapted from programs/reg/tests/reg.c */ +#define verify_reg(k,v,t,d,s,todo) verify_reg_(__LINE__,k,v,t,d,s,todo) +static void verify_reg_(unsigned line, HKEY hkey, const char *value, + DWORD exp_type, const void *exp_data, DWORD exp_size, DWORD todo) { - LONG lr; - DWORD fnd_type, fnd_len; - char fnd_value[1024]; - - fnd_len = sizeof(fnd_value); - lr = RegQueryValueExA(key, value_name, NULL, &fnd_type, (BYTE*)fnd_value, &fnd_len); - lok(lr == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", lr); - if(lr != ERROR_SUCCESS) + DWORD type, size; + BYTE data[256]; + LONG err; + + size = sizeof(data); + memset(data, 0xdd, size); + err = RegQueryValueExA(hkey, value, NULL, &type, data, &size); + lok(err == ERROR_SUCCESS, "RegQueryValueEx failed: got %d\n", err); + if (err != ERROR_SUCCESS) return; - lok(fnd_type == REG_SZ, "Got wrong type: %d\n", fnd_type); - if(fnd_type != REG_SZ) - return; - lok(!strcmp(exp_value, fnd_value), - "Strings differ: expected %s, got %s\n", exp_value, fnd_value); + todo_wine_if (todo & TODO_REG_TYPE) + lok(type == exp_type, "got wrong type %d, expected %d\n", type, exp_type); + todo_wine_if (todo & TODO_REG_SIZE) + lok(size == exp_size, "got wrong size %d, expected %d\n", size, exp_size); + todo_wine_if (todo & TODO_REG_DATA) + lok(memcmp(data, exp_data, size) == 0, "got wrong data\n"); } #define verify_reg_wsz(k,n,e) r_verify_reg_wsz(__LINE__,k,n,e) @@ -142,48 +150,6 @@ static void r_verify_reg_wsz(unsigned line, HKEY key, const char *value_name, co wine_dbgstr_w(exp_value), wine_dbgstr_w(fnd_value)); } -#define verify_reg_dword(k,n,e) r_verify_reg_dword(__LINE__,k,n,e) -static void r_verify_reg_dword(unsigned line, HKEY key, const char *value_name, DWORD exp_value) -{ - LONG lr; - DWORD fnd_type, fnd_len, fnd_value; - - fnd_len = sizeof(fnd_value); - lr = RegQueryValueExA(key, value_name, NULL, &fnd_type, (BYTE *)&fnd_value, &fnd_len); - lok(lr == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", lr); - if(lr != ERROR_SUCCESS) - return; - - lok(fnd_type == REG_DWORD, "Got wrong type: %d\n", fnd_type); - if(fnd_type != REG_DWORD) - return; - lok(fnd_value == exp_value, "Values differ: expected: 0x%x, got: 0x%x\n", - exp_value, fnd_value); -} - -#define verify_reg_binary(k,n,e,z) r_verify_reg_binary(__LINE__,k,n,e,z) -static void r_verify_reg_binary(unsigned line, HKEY key, - const char *value_name, const char *exp_value, int exp_len) -{ - LONG lr; - DWORD fnd_type, fnd_len; - char fnd_value[1024]; - - fnd_len = sizeof(fnd_value); - lr = RegQueryValueExA(key, value_name, NULL, &fnd_type, (BYTE*)fnd_value, &fnd_len); - lok(lr == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", lr); - if(lr != ERROR_SUCCESS) - return; - - lok(fnd_type == REG_BINARY, "Got wrong type: %d\n", fnd_type); - if(fnd_type != REG_BINARY) - return; - lok(fnd_len == exp_len, - "Lengths differ: expected %d, got %d\n", exp_len, fnd_len); - lok(!memcmp(exp_value, fnd_value, exp_len), - "Data differs\n"); -} - #define verify_reg_nonexist(k,n) r_verify_reg_nonexist(__LINE__,k,n) static void r_verify_reg_nonexist(unsigned line, HKEY key, const char *value_name) { @@ -202,6 +168,7 @@ static void r_verify_reg_nonexist(unsigned line, HKEY key, const char *value_nam static void test_basic_import(void) { HKEY hkey; + DWORD dword = 0x17; char exp_binary[] = {0xAA,0xBB,0xCC,0x11}; WCHAR wide_test[] = {0xFEFF,'W','i','n','d','o','w','s',' ','R','e','g', 'i','s','t','r','y',' ','E','d','i','t','o','r',' ','V','e','r','s', @@ -231,12 +198,12 @@ static void test_basic_import(void) "\"TestValue\"=\"AValue\"\n"); lr = RegOpenKeyExA(HKEY_CURRENT_USER, KEY_BASE, 0, KEY_READ, &hkey); ok(lr == ERROR_SUCCESS, "RegOpenKeyExA failed: %d\n", lr); - verify_reg_sz(hkey, "TestValue", "AValue"); + verify_reg(hkey, "TestValue", REG_SZ, "AValue", 7, 0); exec_import_str("REGEDIT4\r\n\r\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\r\n" "\"TestValue2\"=\"BValue\"\r\n"); - verify_reg_sz(hkey, "TestValue2", "BValue"); + verify_reg(hkey, "TestValue2", REG_SZ, "BValue", 7, 0); if (supports_wchar) { @@ -252,22 +219,22 @@ static void test_basic_import(void) exec_import_str("REGEDIT4\r\r" "[HKEY_CURRENT_USER\\" KEY_BASE "]\r" "\"TestValue4\"=\"DValue\"\r"); - verify_reg_sz(hkey, "TestValue4", "DValue"); + verify_reg(hkey, "TestValue4", REG_SZ, "DValue", 7, 0); exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"TestDword\"=dword:00000017\n"); - verify_reg_dword(hkey, "TestDword", 0x17); + verify_reg(hkey, "TestDword", REG_DWORD, &dword, sizeof(dword), 0); exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"TestBinary\"=hex:aa,bb,cc,11\n"); - verify_reg_binary(hkey, "TestBinary", exp_binary, sizeof(exp_binary)); + verify_reg(hkey, "TestBinary", REG_BINARY, exp_binary, sizeof(exp_binary), 0); exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"With=Equals\"=\"asdf\"\n"); - verify_reg_sz(hkey, "With=Equals", "asdf"); + verify_reg(hkey, "With=Equals", REG_SZ, "asdf", 5, 0); RegCloseKey(hkey); -- 2.7.4 From hugh.mcmaster at outlook.com Mon Oct 24 06:27:37 2016 From: hugh.mcmaster at outlook.com (Hugh McMaster) Date: Mon, 24 Oct 2016 11:27:37 +0000 Subject: [PATCH 4/4] regedit/tests: Add line break and complexity tests In-Reply-To: <1477308397-6931-1-git-send-email-hugh.mcmaster@outlook.com> References: <1477308397-6931-1-git-send-email-hugh.mcmaster@outlook.com> Message-ID: Signed-off-by: Hugh McMaster --- programs/regedit/tests/regedit.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/programs/regedit/tests/regedit.c b/programs/regedit/tests/regedit.c index eeff9d8..9692c06 100644 --- a/programs/regedit/tests/regedit.c +++ b/programs/regedit/tests/regedit.c @@ -236,6 +236,39 @@ static void test_basic_import(void) "\"With=Equals\"=\"asdf\"\n"); verify_reg(hkey, "With=Equals", REG_SZ, "asdf", 5, 0); + exec_import_str("REGEDIT4\n\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" + "\"Line1\"=\"Value1\"\n\n" + "\"Line2\"=\"Value2\"\n\n\n" + "\"Line3\"=\"Value3\"\n\n\n\n" + "\"Line4\"=\"Value4\"\n\n"); + verify_reg(hkey, "Line1", REG_SZ, "Value1", 7, 0); + todo_wine verify_reg(hkey, "Line2", REG_SZ, "Value2", 7, TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + todo_wine verify_reg(hkey, "Line3", REG_SZ, "Value3", 7, TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + todo_wine verify_reg(hkey, "Line4", REG_SZ, "Value4", 7, TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + + exec_import_str("REGEDIT4\n\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" + "\"Wine1\"=dword:00000782\n\n" + "\"Wine2\"=\"Test Value\"\n" + "\"Wine3\"=hex(7):4c,69,6e,65,20,\ + 63,6f,6e,63,61,74,65,6e,61,74,69,6f,6e,00,00\n" + "#comment\n" + "@=\"Test\"\n" + ";comment\n\n" + "\"Wine4\"=dword:12345678\n\n"); + dword = 0x782; + verify_reg(hkey, "Wine1", REG_DWORD, &dword, sizeof(dword), 0); + todo_wine verify_reg(hkey, "Wine2", REG_SZ, "Test Value", 11, + TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + todo_wine verify_reg(hkey, "Wine3", REG_MULTI_SZ, "Line concatenation\0", 20, + TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + todo_wine verify_reg(hkey, "", REG_SZ, "Test", 5, + TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + dword = 0x12345678; + todo_wine verify_reg(hkey, "Wine4", REG_DWORD, &dword, sizeof(dword), + TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + RegCloseKey(hkey); lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); -- 2.7.4 From hugh.mcmaster at outlook.com Mon Oct 24 06:28:32 2016 From: hugh.mcmaster at outlook.com (Hugh McMaster) Date: Mon, 24 Oct 2016 11:28:32 +0000 Subject: reg/tests: Add line break and complexity tests for 'reg import' Message-ID: Signed-off-by: Hugh McMaster --- programs/reg/tests/reg.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/programs/reg/tests/reg.c b/programs/reg/tests/reg.c index 1e3d1d2..794ebbc 100644 --- a/programs/reg/tests/reg.c +++ b/programs/reg/tests/reg.c @@ -908,6 +908,42 @@ static void test_import(void) todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); todo_wine verify_reg(hkey, "Test6", REG_SZ, "Value6", 7, 0); + test_import_str("REGEDIT4\n\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" + "\"Line1\"=\"Value1\"\n\n" + "\"Line2\"=\"Value2\"\n\n\n" + "\"Line3\"=\"Value3\"\n\n\n\n" + "\"Line4\"=\"Value4\"\n\n", &r); + todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + todo_wine verify_reg(hkey, "Line1", REG_SZ, "Value1", 7, TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + todo_wine verify_reg(hkey, "Line2", REG_SZ, "Value2", 7, TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + todo_wine verify_reg(hkey, "Line3", REG_SZ, "Value3", 7, TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + todo_wine verify_reg(hkey, "Line4", REG_SZ, "Value4", 7, TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + + test_import_str("REGEDIT4\n\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" + "\"Wine1\"=dword:00000782\n\n" + "\"Wine2\"=\"Test Value\"\n" + "\"Wine3\"=hex(7):4c,69,6e,65,20,\ + 63,6f,6e,63,61,74,65,6e,61,74,69,6f,6e,00,00\n" + "#comment\n" + "@=\"Test\"\n" + ";comment\n\n" + "\"Wine4\"=dword:12345678\n\n", &r); + todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + dword = 0x782; + todo_wine verify_reg(hkey, "Wine1", REG_DWORD, &dword, sizeof(dword), + TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + todo_wine verify_reg(hkey, "Wine2", REG_SZ, "Test Value", 11, + TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + todo_wine verify_reg(hkey, "Wine3", REG_MULTI_SZ, "Line concatenation\0", 20, + TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + todo_wine verify_reg(hkey, "", REG_SZ, "Test", 5, + TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + dword = 0x12345678; + todo_wine verify_reg(hkey, "Wine4", REG_DWORD, &dword, sizeof(dword), + TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + err = RegCloseKey(hkey); todo_wine ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); -- 2.7.4 From huw at codeweavers.com Mon Oct 24 08:11:55 2016 From: huw at codeweavers.com (Huw Davies) Date: Mon, 24 Oct 2016 14:11:55 +0100 Subject: ntdll: Zero-init the buffer for non-linux versions of SystemProcessorPerformanceInformation. Message-ID: <1477314715-3768-1-git-send-email-huw@codeweavers.com> This ensures that the unused fields are set to zero, which matches the linux version. Signed-off-by: Huw Davies --- dlls/ntdll/nt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index 46393a4..e0f6df0 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -2062,7 +2062,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( int i; cpus = min(cpus,out_cpus); len = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * cpus; - sppi = RtlAllocateHeap(GetProcessHeap(), 0,len); + sppi = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, len); for (i = 0; i < cpus; i++) { sppi[i].IdleTime.QuadPart = pinfo[i].cpu_ticks[CPU_STATE_IDLE]; @@ -2118,7 +2118,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( unsigned int n; cpus = min(NtCurrentTeb()->Peb->NumberOfProcessors, out_cpus); len = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * cpus; - sppi = RtlAllocateHeap(GetProcessHeap(), 0, len); + sppi = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, len); FIXME("stub info_class SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION\n"); /* many programs expect these values to change so fake change */ for (n = 0; n < cpus; n++) -- 2.7.4 From jacek at codeweavers.com Mon Oct 24 08:58:30 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 24 Oct 2016 15:58:30 +0200 Subject: [PATCH 01/10 resend] server: Introduced iosb struct for server-side IO_STATUS_BLOCK representation and use it in irp_call. Message-ID: <712db96b-01a9-75c3-2ef1-dfba9ebf6745@codeweavers.com> resend: Rebased after Ken's patch. Signed-off-by: Jacek Caban --- server/async.c | 34 +++++++++++++++++++++++++++++++++ server/device.c | 58 +++++++++++++++++++++++++-------------------------------- server/file.h | 14 ++++++++++++++ 3 files changed, 73 insertions(+), 33 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-server-Introduced-iosb-struct-for-server-side-IO_STAT.diff Type: text/x-patch Size: 7915 bytes Desc: not available URL: From jacek at codeweavers.com Mon Oct 24 08:58:40 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 24 Oct 2016 15:58:40 +0200 Subject: [PATCH 02/10] server: Store iosb in async object. Message-ID: Signed-off-by: Jacek Caban --- server/async.c | 15 ++++++++++++++- server/change.c | 2 +- server/device.c | 2 +- server/fd.c | 6 +++--- server/file.h | 5 +++-- server/mailslot.c | 2 +- server/named_pipe.c | 6 +++--- server/serial.c | 2 +- server/sock.c | 4 ++-- 9 files changed, 29 insertions(+), 15 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-server-Store-iosb-in-async-object.diff Type: text/x-patch Size: 9940 bytes Desc: not available URL: From jacek at codeweavers.com Mon Oct 24 08:58:44 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 24 Oct 2016 15:58:44 +0200 Subject: [PATCH 03/10] server: Use async object to transfer IRP result to client. Message-ID: <3f9a1313-0961-a645-d4bd-b5120ecf12c9@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/ntdll/file.c | 2 +- server/async.c | 21 +++++++++++++++++++ server/change.c | 3 ++- server/console.c | 3 ++- server/device.c | 58 ++++++----------------------------------------------- server/fd.c | 43 +++++++++++++++++++++++++++++++++++++++ server/file.c | 3 ++- server/file.h | 5 +++++ server/mailslot.c | 9 ++++++--- server/mapping.c | 3 ++- server/protocol.def | 19 +++++++++--------- server/serial.c | 3 ++- server/sock.c | 6 ++++-- 13 files changed, 105 insertions(+), 73 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0003-server-Use-async-object-to-transfer-IRP-result-to-cli.diff Type: text/x-patch Size: 15241 bytes Desc: not available URL: From jacek at codeweavers.com Mon Oct 24 08:58:48 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 24 Oct 2016 15:58:48 +0200 Subject: [PATCH 04/10] server: Introduced new pipe_end struct containing common parts of pipe_client and pipe_server. Message-ID: <2abe22b1-d695-594a-4494-d178d15ead4d@codeweavers.com> Signed-off-by: Jacek Caban --- server/named_pipe.c | 99 ++++++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 46 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0004-server-Introduced-new-pipe_end-struct-containing-comm.diff Type: text/x-patch Size: 11613 bytes Desc: not available URL: From jacek at codeweavers.com Mon Oct 24 08:58:59 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 24 Oct 2016 15:58:59 +0200 Subject: [PATCH 06/10] server: Signal pipe server fd in create_pipe_servr. Message-ID: Signed-off-by: Jacek Caban --- dlls/kernel32/tests/pipe.c | 8 ++++++++ server/named_pipe.c | 1 + 2 files changed, 9 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0006-server-Signal-pipe-server-fd-in-create_pipe_servr.diff Type: text/x-patch Size: 1412 bytes Desc: not available URL: From jacek at codeweavers.com Mon Oct 24 08:59:06 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 24 Oct 2016 15:59:06 +0200 Subject: [PATCH 07/10] server: Added support for message mode named pipes. Message-ID: Signed-off-by: Jacek Caban --- dlls/kernel32/tests/pipe.c | 74 ++----- dlls/ntdll/file.c | 7 +- dlls/ntdll/tests/file.c | 2 +- server/async.c | 9 + server/file.h | 1 + server/named_pipe.c | 532 ++++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 535 insertions(+), 90 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0007-server-Added-support-for-message-mode-named-pipes.diff Type: text/x-patch Size: 45832 bytes Desc: not available URL: From jacek at codeweavers.com Mon Oct 24 08:59:10 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 24 Oct 2016 15:59:10 +0200 Subject: [PATCH 08/10] server: Added support for flushing client pipe. Message-ID: <580ba887-61af-ccc6-ab26-3703ba0f653b@codeweavers.com> Signed-off-by: Jacek Caban --- server/named_pipe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0008-server-Added-support-for-flushing-client-pipe.diff Type: text/x-patch Size: 669 bytes Desc: not available URL: From jacek at codeweavers.com Mon Oct 24 08:59:20 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 24 Oct 2016 15:59:20 +0200 Subject: [PATCH 09/10] kernel32/tests: Added more named pipe tests. Message-ID: <5fcd7cc2-35c1-4513-dbd2-e520a6ac55b0@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/kernel32/tests/pipe.c | 384 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 384 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0009-kernel32-tests-Added-more-named-pipe-tests.diff Type: text/x-patch Size: 17656 bytes Desc: not available URL: From jacek at codeweavers.com Mon Oct 24 08:59:23 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 24 Oct 2016 15:59:23 +0200 Subject: [PATCH 10/10] kernel32/tests: Added tests of real buffer size. Message-ID: <36035d38-a9d4-855c-b283-280ff94387ea@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/kernel32/tests/pipe.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0010-kernel32-tests-Added-tests-of-real-buffer-size.diff Type: text/x-patch Size: 2576 bytes Desc: not available URL: From jacek at codeweavers.com Mon Oct 24 08:59:35 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 24 Oct 2016 15:59:35 +0200 Subject: [PATCH 05/10] server: Moved server-independent parts of pipe_server_flush into separated function. Message-ID: <67908ae3-cd49-db89-e4d1-5753553a583e@codeweavers.com> Signed-off-by: Jacek Caban --- server/named_pipe.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0005-server-Moved-server-independent-parts-of-pipe_server_.diff Type: text/x-patch Size: 2150 bytes Desc: not available URL: From aric at codeweavers.com Mon Oct 24 09:06:46 2016 From: aric at codeweavers.com (Aric Stewart) Date: Mon, 24 Oct 2016 09:06:46 -0500 Subject: [PATCH] hid: implement HidD_SetOutputReport Message-ID: Also fixes an issue with IOCTL_HID_SET_FEATURE where the wrong buffers where being sent. Signed-off-by: Aric Stewart --- dlls/hid/hid.spec | 2 +- dlls/hid/hidd.c | 6 ++++++ dlls/hidclass.sys/device.c | 11 +++++++---- include/ddk/hidsdi.h | 1 + 4 files changed, 15 insertions(+), 5 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-hid-implement-HidD_SetOutputReport.txt Type: text/x-patch Size: 3331 bytes Desc: not available URL: From jacek at codeweavers.com Mon Oct 24 10:48:49 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 24 Oct 2016 17:48:49 +0200 Subject: [PATCH 1/2] ntdll: Cache error information for cacheable handles with no fd. Message-ID: <905ea4cd-49b6-876f-2ea8-4d7528942d38@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/ntdll/server.c | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-ntdll-Cache-error-information-for-cacheable-handles-w.diff Type: text/x-patch Size: 3264 bytes Desc: not available URL: From jacek at codeweavers.com Mon Oct 24 10:48:56 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Mon, 24 Oct 2016 17:48:56 +0200 Subject: [PATCH 2/2] server: Allow caching device file handles. Message-ID: <1bb6fc25-51a7-8167-14a0-c4fd8ef7ddd3@codeweavers.com> Signed-off-by: Jacek Caban --- server/device.c | 2 ++ server/fd.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-server-Allow-caching-device-file-handles.diff Type: text/x-patch Size: 1014 bytes Desc: not available URL: From ken at codeweavers.com Mon Oct 24 11:53:46 2016 From: ken at codeweavers.com (Ken Thomases) Date: Mon, 24 Oct 2016 11:53:46 -0500 Subject: winemac: Update the keyboard layout data immediately after changing the input source. In-Reply-To: <1477300518-37075-1-git-send-email-huw@codeweavers.com> References: <1477300518-37075-1-git-send-email-huw@codeweavers.com> Message-ID: Signed-off-by: Ken Thomases From piotr at codeweavers.com Mon Oct 24 13:46:14 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Mon, 24 Oct 2016 20:46:14 +0200 Subject: [PATCH] gdiplus: Fix GdipCreateLineBrushFromRectWithAngle implementation Message-ID: <3b0ed926-5b0c-5f1f-6795-2f784e29107d@codeweavers.com> The patch fixes isAngleScalable==TRUE argument handling. It also fixes a mistake when width was used instead of height. Signed-off-by: Piotr Caban --- dlls/gdiplus/brush.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-gdiplus-Fix-GdipCreateLineBrushFromRectWithAngle-imple.txt Type: text/x-patch Size: 2579 bytes Desc: not available URL: From andrey.goosev at gmail.com Mon Oct 24 14:59:33 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Mon, 24 Oct 2016 22:59:33 +0300 Subject: po: Update Ukrainian translation. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: po-Update-Ukrainian-translation.patch Type: text/x-patch Size: 2179 bytes Desc: not available URL: From nsivov at codeweavers.com Tue Oct 25 00:11:45 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Tue, 25 Oct 2016 08:11:45 +0300 Subject: [PATCH] d3drm: Remove stub messages for implemented methods TRACEs Message-ID: <20161025051145.6809-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/d3drm/device.c | 4 ++-- dlls/d3drm/frame.c | 2 +- dlls/d3drm/meshbuilder.c | 2 +- dlls/d3drm/texture.c | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dlls/d3drm/device.c b/dlls/d3drm/device.c index 57fd7c0..ef83de0 100644 --- a/dlls/d3drm/device.c +++ b/dlls/d3drm/device.c @@ -1146,7 +1146,7 @@ static D3DCOLORMODEL WINAPI d3drm_device1_GetColorModel(IDirect3DRMDevice *iface { struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface); - TRACE("iface %p stub!\n", iface); + TRACE("iface %p.\n", iface); return d3drm_device3_GetColorModel(&device->IDirect3DRMDevice3_iface); } @@ -1580,7 +1580,7 @@ static HRESULT WINAPI d3drm_device_win_GetName(IDirect3DRMWinDevice *iface, DWOR { struct d3drm_device *device = impl_from_IDirect3DRMWinDevice(iface); - TRACE("iface %p, size %p, name %p stub!\n", iface, size, name); + TRACE("iface %p, size %p, name %p.\n", iface, size, name); return d3drm_device3_GetName(&device->IDirect3DRMDevice3_iface, size, name); } diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index d79a8e3..978b1d8 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -2002,7 +2002,7 @@ static HRESULT WINAPI d3drm_frame3_SetSceneBackgroundRGB(IDirect3DRMFrame3 *ifac { struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); - TRACE("iface %p, red %.8e, green %.8e, blue %.8e stub!\n", iface, red, green, blue); + TRACE("iface %p, red %.8e, green %.8e, blue %.8e.\n", iface, red, green, blue); frame->scenebackground = RGBA_MAKE((BYTE)(red * 255.0f), (BYTE)(green * 255.0f), (BYTE)(blue * 255.0f), 0xff); diff --git a/dlls/d3drm/meshbuilder.c b/dlls/d3drm/meshbuilder.c index 72c4473..958e759 100644 --- a/dlls/d3drm/meshbuilder.c +++ b/dlls/d3drm/meshbuilder.c @@ -2211,7 +2211,7 @@ static HRESULT WINAPI d3drm_mesh_builder3_GetNormals(IDirect3DRMMeshBuilder3 *if struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); DWORD count = mesh_builder->nb_normals - start_idx; - TRACE("iface %p, start_idx %u, normal_count %p, normals %p stub!\n", + TRACE("iface %p, start_idx %u, normal_count %p, normals %p.\n", iface, start_idx, normal_count, normals); if (normal_count) diff --git a/dlls/d3drm/texture.c b/dlls/d3drm/texture.c index 83d07dc..6c622b6 100644 --- a/dlls/d3drm/texture.c +++ b/dlls/d3drm/texture.c @@ -222,7 +222,7 @@ static HRESULT WINAPI d3drm_texture1_SetDecalSize(IDirect3DRMTexture *iface, D3D { struct d3drm_texture *texture = impl_from_IDirect3DRMTexture(iface); - TRACE("iface %p, width %.8e, height %.8e stub!\n", iface, width, height); + TRACE("iface %p, width %.8e, height %.8e.\n", iface, width, height); return IDirect3DRMTexture3_SetDecalSize(&texture->IDirect3DRMTexture3_iface, width, height); } @@ -522,7 +522,7 @@ static HRESULT WINAPI d3drm_texture2_SetDecalSize(IDirect3DRMTexture2 *iface, D3 { struct d3drm_texture *texture = impl_from_IDirect3DRMTexture2(iface); - TRACE("iface %p, width %.8e, height %.8e stub!\n", iface, width, height); + TRACE("iface %p, width %.8e, height %.8e.\n", iface, width, height); return IDirect3DRMTexture3_SetDecalSize(&texture->IDirect3DRMTexture3_iface, width, height); } -- 2.9.3 From nsivov at codeweavers.com Tue Oct 25 00:18:40 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Tue, 25 Oct 2016 08:18:40 +0300 Subject: [PATCH] wincodecs: Remove stub message for implemented methods Message-ID: <20161025051840.15219-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/windowscodecs/converter.c | 4 ++-- dlls/windowscodecs/icnsformat.c | 2 +- dlls/windowscodecs/tiffformat.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dlls/windowscodecs/converter.c b/dlls/windowscodecs/converter.c index 7ff6bec..e5bce44 100644 --- a/dlls/windowscodecs/converter.c +++ b/dlls/windowscodecs/converter.c @@ -1287,7 +1287,7 @@ static HRESULT WINAPI FormatConverter_GetPixelFormat(IWICFormatConverter *iface, { FormatConverter *This = impl_from_IWICFormatConverter(iface); - TRACE("(%p,%p): stub\n", iface, pPixelFormat); + TRACE("(%p,%p)\n", iface, pPixelFormat); if (This->source) memcpy(pPixelFormat, This->dst_format->guid, sizeof(GUID)); @@ -1302,7 +1302,7 @@ static HRESULT WINAPI FormatConverter_GetResolution(IWICFormatConverter *iface, { FormatConverter *This = impl_from_IWICFormatConverter(iface); - TRACE("(%p,%p,%p): stub\n", iface, pDpiX, pDpiY); + TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY); if (This->source) return IWICBitmapSource_GetResolution(This->source, pDpiX, pDpiY); diff --git a/dlls/windowscodecs/icnsformat.c b/dlls/windowscodecs/icnsformat.c index 552fa39..14144f7 100644 --- a/dlls/windowscodecs/icnsformat.c +++ b/dlls/windowscodecs/icnsformat.c @@ -415,7 +415,7 @@ static HRESULT WINAPI IcnsFrameEncode_Commit(IWICBitmapFrameEncode *iface) OSErr ret; HRESULT hr = S_OK; - TRACE("(%p): stub\n", iface); + TRACE("(%p)\n", iface); EnterCriticalSection(&This->encoder->lock); diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c index 1dacd87..0e2a5d5 100644 --- a/dlls/windowscodecs/tiffformat.c +++ b/dlls/windowscodecs/tiffformat.c @@ -626,7 +626,7 @@ static HRESULT WINAPI TiffDecoder_Initialize(IWICBitmapDecoder *iface, IStream * TIFF *tiff; HRESULT hr=S_OK; - TRACE("(%p,%p,%x): stub\n", iface, pIStream, cacheOptions); + TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); EnterCriticalSection(&This->lock); -- 2.9.3 From nsivov at codeweavers.com Tue Oct 25 00:21:27 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Tue, 25 Oct 2016 08:21:27 +0300 Subject: [PATCH] uxtheme: Remove stub message for implemented functions Message-ID: <20161025052127.15425-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/uxtheme/draw.c | 2 +- dlls/uxtheme/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/uxtheme/draw.c b/dlls/uxtheme/draw.c index 8f0eabe..2a37a56 100644 --- a/dlls/uxtheme/draw.c +++ b/dlls/uxtheme/draw.c @@ -2016,7 +2016,7 @@ HRESULT WINAPI GetThemeTextExtent(HTHEME hTheme, HDC hdc, int iPartId, LOGFONTW logfont; RECT rt = {0,0,0xFFFF,0xFFFF}; - TRACE("%d %d: stub\n", iPartId, iStateId); + TRACE("%d %d\n", iPartId, iStateId); if(!hTheme) return E_HANDLE; diff --git a/dlls/uxtheme/main.c b/dlls/uxtheme/main.c index 5c0acf1..73894e8 100644 --- a/dlls/uxtheme/main.c +++ b/dlls/uxtheme/main.c @@ -35,7 +35,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(uxtheme); /* For the moment, do nothing here. */ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) { - TRACE("%p 0x%x %p: stub\n", hInstDLL, fdwReason, lpv); + TRACE("%p 0x%x %p\n", hInstDLL, fdwReason, lpv); switch(fdwReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hInstDLL); -- 2.9.3 From nsivov at codeweavers.com Tue Oct 25 00:26:30 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Tue, 25 Oct 2016 08:26:30 +0300 Subject: [PATCH] quartz: Remove stub messages for implemented methods Message-ID: <20161025052630.15698-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/quartz/filtermapper.c | 2 +- dlls/quartz/vmr9.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dlls/quartz/filtermapper.c b/dlls/quartz/filtermapper.c index 8a1fc3a..4e4cb37 100644 --- a/dlls/quartz/filtermapper.c +++ b/dlls/quartz/filtermapper.c @@ -1157,7 +1157,7 @@ static HRESULT WINAPI FilterMapper_EnumMatchingFilters( REGFILTER* regfilters; HRESULT hr; - TRACE("(%p/%p)->(%p, %x, %s, %s, %s, %s, %s, %s, %s) stub!\n", + TRACE("(%p/%p)->(%p, %x, %s, %s, %s, %s, %s, %s, %s)\n", This, iface, ppEnum, diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c index fb6745d..3c8393f 100644 --- a/dlls/quartz/vmr9.c +++ b/dlls/quartz/vmr9.c @@ -1256,7 +1256,7 @@ static HRESULT WINAPI VMR7FilterConfig_GetRenderingMode(IVMRFilterConfig *iface, { struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface); - TRACE("(%p/%p)->(%p) stub\n", iface, This, mode); + TRACE("(%p/%p)->(%p)\n", iface, This, mode); if (!mode) return E_POINTER; if (This->mode) @@ -1679,7 +1679,7 @@ static HRESULT WINAPI VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9 *iface { struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface); - TRACE("(%p/%p)->(%p) stub\n", iface, This, mode); + TRACE("(%p/%p)->(%p)\n", iface, This, mode); if (!mode) return E_POINTER; -- 2.9.3 From nsivov at codeweavers.com Tue Oct 25 00:37:39 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Tue, 25 Oct 2016 08:37:39 +0300 Subject: [PATCH] advapi32: Remove stub message from implemented function Message-ID: <20161025053739.16013-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/advapi32/security.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index 92a1789..28331df 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -791,7 +791,7 @@ BOOL WINAPI SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass, LPVOID tokeninfo, DWORD tokeninfolength ) { - TRACE("(%p, %s, %p, %d): stub\n", + TRACE("(%p, %s, %p, %d)\n", token, (tokeninfoclass == TokenUser) ? "TokenUser" : (tokeninfoclass == TokenGroups) ? "TokenGroups" : -- 2.9.3 From m4sk1n at o2.pl Mon Oct 24 13:55:03 2016 From: m4sk1n at o2.pl (m4sk1n) Date: Mon, 24 Oct 2016 20:55:03 +0200 Subject: =?UTF-8?Q?Polish_translation?= Message-ID: Here is translated .po file from my GlotPress. Hope it will be used. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: wine-pl.po URL: From hans at codeweavers.com Tue Oct 25 02:11:47 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Tue, 25 Oct 2016 09:11:47 +0200 Subject: msi: Accept descriptors without component. Message-ID: <1477379507-20648-1-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/msi/registry.c | 37 +++++++++++++++++++++++-------------- dlls/msi/tests/db.c | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/dlls/msi/registry.c b/dlls/msi/registry.c index f3b1ddf..8e6f0a1 100644 --- a/dlls/msi/registry.c +++ b/dlls/msi/registry.c @@ -1024,7 +1024,8 @@ UINT MSIREG_DeleteClassesUpgradeCodesKey(LPCWSTR szUpgradeCode) * * Decomposes an MSI descriptor into product, feature and component parts. * An MSI descriptor is a string of the form: - * [base 85 guid] [feature code] '>' [base 85 guid] + * [base 85 guid] [feature code] '>' [base 85 guid] or + * [base 85 guid] [feature code] '<' * * PARAMS * szDescriptor [I] the descriptor to decompose @@ -1041,21 +1042,21 @@ UINT MSIREG_DeleteClassesUpgradeCodesKey(LPCWSTR szUpgradeCode) UINT WINAPI MsiDecomposeDescriptorW( LPCWSTR szDescriptor, LPWSTR szProduct, LPWSTR szFeature, LPWSTR szComponent, LPDWORD pUsed ) { - UINT r, len; - LPWSTR p; + UINT len; + const WCHAR *p; GUID product, component; TRACE("%s %p %p %p %p\n", debugstr_w(szDescriptor), szProduct, szFeature, szComponent, pUsed); - r = decode_base85_guid( szDescriptor, &product ); - if( !r ) + if (!decode_base85_guid( szDescriptor, &product )) return ERROR_INVALID_PARAMETER; TRACE("product %s\n", debugstr_guid( &product )); - p = strchrW(&szDescriptor[20],'>'); - if( !p ) + if (!(p = strchrW( &szDescriptor[20], '>' ))) + p = strchrW( &szDescriptor[20], '<' ); + if (!p) return ERROR_INVALID_PARAMETER; len = (p - &szDescriptor[20]); @@ -1064,22 +1065,30 @@ UINT WINAPI MsiDecomposeDescriptorW( LPCWSTR szDescriptor, LPWSTR szProduct, TRACE("feature %s\n", debugstr_wn( &szDescriptor[20], len )); - r = decode_base85_guid( p+1, &component ); - if( !r ) - return ERROR_INVALID_PARAMETER; - - TRACE("component %s\n", debugstr_guid( &component )); + if (*p == '>') + { + if (!decode_base85_guid( p+1, &component )) + return ERROR_INVALID_PARAMETER; + TRACE( "component %s\n", debugstr_guid(&component) ); + } if (szProduct) StringFromGUID2( &product, szProduct, MAX_FEATURE_CHARS+1 ); if (szComponent) - StringFromGUID2( &component, szComponent, MAX_FEATURE_CHARS+1 ); + { + if (*p == '>') + StringFromGUID2( &component, szComponent, MAX_FEATURE_CHARS+1 ); + else + szComponent[0] = 0; + } if (szFeature) { memcpy( szFeature, &szDescriptor[20], len*sizeof(WCHAR) ); szFeature[len] = 0; } - len = ( &p[21] - szDescriptor ); + + len = p - szDescriptor + 1; + if (*p == '>') len += 20; TRACE("length = %d\n", len); if (pUsed) *pUsed = len; diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index 9c1fcba..278b45f 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -470,6 +470,7 @@ static void test_msidecomposedesc(void) /* test a valid feature descriptor */ desc = "']gAVn-}f(ZXfeAR6.jiFollowTheWhiteRabbit>3w2x^IGfe?CxI5heAvk."; len = 0; + prod[0] = feature[0] = comp[0] = 0; r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len); ok(r == ERROR_SUCCESS, "returned an error\n"); ok(len == strlen(desc), "length was wrong\n"); @@ -485,6 +486,28 @@ static void test_msidecomposedesc(void) r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len); ok(r == ERROR_INVALID_PARAMETER, "returned wrong error\n"); + /* test a feature descriptor with < instead of > */ + desc = "']gAVn-}f(ZXfeAR6.jiFollowTheWhiteRabbit<3w2x^IGfe?CxI5heAvk."; + len = 0; + prod[0] = feature[0] = 0; + comp[0] = 0x55; + r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len); + ok(r == ERROR_SUCCESS, "returned an error\n"); + ok(len == 41, "got %u\n", len); + ok(!strcmp(prod,"{90110409-6000-11D3-8CFE-0150048383C9}"), "got '%s'\n", prod); + ok(!strcmp(feature,"FollowTheWhiteRabbit"), "got '%s'\n", feature); + ok(!comp[0], "got '%s'\n", comp); + + len = 0; + prod[0] = feature[0] = 0; + comp[0] = 0x55; + r = pMsiDecomposeDescriptorA("yh1BVN)8A$!!!!!MKKSkAlwaysInstalledIntl_1033<", prod, feature, comp, &len); + ok(r == ERROR_SUCCESS, "got %u\n", r); + ok(len == 45, "got %u\n", len); + ok(!strcmp(prod, "{90150000-006E-0409-0000-0000000FF1CE}"), "got '%s'\n", prod); + ok(!strcmp(feature, "AlwaysInstalledIntl_1033"), "got '%s'\n", feature); + ok(!comp[0], "got '%s'\n", comp); + /* * Test a valid feature descriptor with the * maximum number of characters and some trailing characters. -- 2.1.4 From hugh.mcmaster at outlook.com Tue Oct 25 05:21:19 2016 From: hugh.mcmaster at outlook.com (Hugh McMaster) Date: Tue, 25 Oct 2016 10:21:19 +0000 Subject: [PATCH 1/2] regedit: Do not close the registy key handle when a line break is encountered Message-ID: Signed-off-by: Hugh McMaster --- programs/regedit/regproc.c | 6 ------ programs/regedit/tests/regedit.c | 18 +++++++----------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/programs/regedit/regproc.c b/programs/regedit/regproc.c index 7c5105f..7f1475e 100644 --- a/programs/regedit/regproc.c +++ b/programs/regedit/regproc.c @@ -614,12 +614,6 @@ static void processRegEntry(WCHAR* stdInput, BOOL isUnicode) ( stdInput[0] == '\"'))) /* reading a new value=data pair */ { processSetValue(stdInput, isUnicode); - } else - { - /* Since we are assuming that the file format is valid we must be - * reading a blank line which indicates the end of this key processing - */ - closeKey(); } } diff --git a/programs/regedit/tests/regedit.c b/programs/regedit/tests/regedit.c index 9692c06..efd7715 100644 --- a/programs/regedit/tests/regedit.c +++ b/programs/regedit/tests/regedit.c @@ -243,9 +243,9 @@ static void test_basic_import(void) "\"Line3\"=\"Value3\"\n\n\n\n" "\"Line4\"=\"Value4\"\n\n"); verify_reg(hkey, "Line1", REG_SZ, "Value1", 7, 0); - todo_wine verify_reg(hkey, "Line2", REG_SZ, "Value2", 7, TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); - todo_wine verify_reg(hkey, "Line3", REG_SZ, "Value3", 7, TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); - todo_wine verify_reg(hkey, "Line4", REG_SZ, "Value4", 7, TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + verify_reg(hkey, "Line2", REG_SZ, "Value2", 7, 0); + verify_reg(hkey, "Line3", REG_SZ, "Value3", 7, 0); + verify_reg(hkey, "Line4", REG_SZ, "Value4", 7, 0); exec_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" @@ -259,15 +259,11 @@ static void test_basic_import(void) "\"Wine4\"=dword:12345678\n\n"); dword = 0x782; verify_reg(hkey, "Wine1", REG_DWORD, &dword, sizeof(dword), 0); - todo_wine verify_reg(hkey, "Wine2", REG_SZ, "Test Value", 11, - TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); - todo_wine verify_reg(hkey, "Wine3", REG_MULTI_SZ, "Line concatenation\0", 20, - TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); - todo_wine verify_reg(hkey, "", REG_SZ, "Test", 5, - TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + verify_reg(hkey, "Wine2", REG_SZ, "Test Value", 11, 0); + verify_reg(hkey, "Wine3", REG_MULTI_SZ, "Line concatenation\0", 20, 0); + verify_reg(hkey, "", REG_SZ, "Test", 5, 0); dword = 0x12345678; - todo_wine verify_reg(hkey, "Wine4", REG_DWORD, &dword, sizeof(dword), - TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA); + verify_reg(hkey, "Wine4", REG_DWORD, &dword, sizeof(dword), 0); RegCloseKey(hkey); -- 2.7.4 From hugh.mcmaster at outlook.com Tue Oct 25 05:21:32 2016 From: hugh.mcmaster at outlook.com (Hugh McMaster) Date: Tue, 25 Oct 2016 10:21:32 +0000 Subject: [PATCH 2/2] regedit: Close the registry key handle in the read function instead of the parser In-Reply-To: <1477390858-20022-1-git-send-email-hugh.mcmaster@outlook.com> References: <1477390858-20022-1-git-send-email-hugh.mcmaster@outlook.com> Message-ID: Signed-off-by: Hugh McMaster --- programs/regedit/regproc.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/programs/regedit/regproc.c b/programs/regedit/regproc.c index 7f1475e..5e4c2d2 100644 --- a/programs/regedit/regproc.c +++ b/programs/regedit/regproc.c @@ -584,15 +584,6 @@ static void processSetValue(WCHAR* line, BOOL is_unicode) */ static void processRegEntry(WCHAR* stdInput, BOOL isUnicode) { - /* - * We encountered the end of the file, make sure we - * close the opened key and exit - */ - if (stdInput == NULL) { - closeKey(); - return; - } - if ( stdInput[0] == '[') /* We are reading a new key */ { WCHAR* keyEnd; @@ -735,7 +726,7 @@ static void processRegLinesA(FILE *in, char* first_chars) line = s_eol + 1; } } - processRegEntry(NULL, FALSE); + closeKey(); HeapFree(GetProcessHeap(), 0, buf); } @@ -851,7 +842,7 @@ static void processRegLinesW(FILE *in) } } - processRegEntry(NULL, TRUE); + closeKey(); HeapFree(GetProcessHeap(), 0, buf); } -- 2.7.4 From hans at codeweavers.com Tue Oct 25 06:03:18 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Tue, 25 Oct 2016 13:03:18 +0200 Subject: [1/6] webservices: Implement WsReadBytes. Message-ID: <1477393403-7042-1-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/reader.c | 46 +++++++++++++++ dlls/webservices/tests/reader.c | 118 ++++++++++++++++++++++++++++++++++++++ dlls/webservices/webservices.spec | 2 +- include/webservices.h | 3 + 4 files changed, 168 insertions(+), 1 deletion(-) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 9ba4dfc..9a3c7d7 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -590,6 +590,7 @@ struct reader struct xmlbuf *input_buf; const unsigned char *input_data; ULONG input_size; + ULONG text_conv_offset; ULONG prop_count; struct prop prop[sizeof(reader_props)/sizeof(reader_props[0])]; }; @@ -1540,6 +1541,7 @@ static HRESULT read_text( struct reader *reader ) read_insert_node( reader, parent, node ); reader->state = READER_STATE_TEXT; + reader->text_conv_offset = 0; return S_OK; } @@ -4536,3 +4538,47 @@ HRESULT WINAPI WsSetReaderPosition( WS_XML_READER *handle, const WS_XML_NODE_POS reader->current = pos->node; return S_OK; } + +static HRESULT utf8_to_base64( const WS_XML_UTF8_TEXT *utf8, WS_XML_BASE64_TEXT *base64 ) +{ + if (utf8->value.length % 4) return WS_E_INVALID_FORMAT; + if (!(base64->bytes = heap_alloc( utf8->value.length * 3 / 4 ))) return E_OUTOFMEMORY; + base64->length = decode_base64( utf8->value.bytes, utf8->value.length, base64->bytes ); + return S_OK; +} + +/************************************************************************** + * WsReadBytes [webservices.@] + */ +HRESULT WINAPI WsReadBytes( WS_XML_READER *handle, void *bytes, ULONG max_count, ULONG *count, WS_ERROR *error ) +{ + struct reader *reader = (struct reader *)handle; + HRESULT hr; + + TRACE( "%p %p %u %p %p\n", handle, bytes, max_count, count, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!reader) return E_INVALIDARG; + if (!reader->input_type) return WS_E_INVALID_OPERATION; + if (!count) return E_INVALIDARG; + + *count = 0; + if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && bytes) + { + const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)reader->current; + WS_XML_BASE64_TEXT base64; + + if ((hr = utf8_to_base64( (const WS_XML_UTF8_TEXT *)text->text, &base64 )) != S_OK) return hr; + if (reader->text_conv_offset == base64.length) + { + heap_free( base64.bytes ); + return read_node( reader ); + } + *count = min( base64.length - reader->text_conv_offset, max_count ); + memcpy( bytes, base64.bytes + reader->text_conv_offset, *count ); + reader->text_conv_offset += *count; + heap_free( base64.bytes ); + } + + return S_OK; +} diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index 62ed499..c804105 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -3861,6 +3861,123 @@ static void test_field_options(void) WsFreeHeap( heap ); } +static void test_WsReadBytes(void) +{ + HRESULT hr; + WS_XML_READER *reader; + const WS_XML_NODE *node; + const WS_XML_TEXT_NODE *text; + const WS_XML_UTF8_TEXT *utf8; + BYTE buf[4]; + ULONG count; + + hr = WsCreateReader( NULL, 0, &reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadBytes( NULL, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsReadBytes( reader, NULL, 0, NULL, NULL ); + ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr ); + + hr = set_input( reader, "dGV4dA==", sizeof("dGV4dA==") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadBytes( reader, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = set_input( reader, "dGV4dA==", sizeof("dGV4dA==") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadBytes( reader, buf, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = set_input( reader, "dGV4dA==", sizeof("dGV4dA==") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + count = 0xdeadbeef; + hr = WsReadBytes( reader, NULL, 0, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + count = 0xdeadbeef; + hr = WsReadBytes( reader, NULL, 1, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadBytes( reader, buf, 0, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + ok( !buf[0], "wrong data\n" ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadBytes( reader, buf, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + ok( !buf[0], "wrong data\n" ); + + hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadBytes( reader, buf, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + ok( !buf[0], "wrong data\n" ); + + hr = WsReadStartElement( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + count = 0xdeadbeef; + hr = WsReadBytes( reader, NULL, 0, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadBytes( reader, buf, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 2, "got %u\n", count ); + ok( !memcmp( buf, "te", 2 ), "wrong data\n" ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + text = (const WS_XML_TEXT_NODE *)node; + ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType ); + utf8 = (const WS_XML_UTF8_TEXT *)text->text; + ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType ); + ok( utf8->value.length == 8, "got %u\n", utf8->value.length ); + ok( !memcmp( utf8->value.bytes, "dGV4dA==", 8 ), "wrong data\n" ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadBytes( reader, buf, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 2, "got %u\n", count ); + ok( !memcmp( buf, "xt", 2 ), "wrong data\n" ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + text = (const WS_XML_TEXT_NODE *)node; + ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType ); + + count = 0xdeadbeef; + hr = WsReadBytes( reader, buf, 1, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + text = (const WS_XML_TEXT_NODE *)node; + ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType ); + + WsFreeReader( reader ); +} + START_TEST(reader) { test_WsCreateError(); @@ -3897,4 +4014,5 @@ START_TEST(reader) test_WsSetReaderPosition(); test_entities(); test_field_options(); + test_WsReadBytes(); } diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec index a03b7bd..26db0b2 100644 --- a/dlls/webservices/webservices.spec +++ b/dlls/webservices/webservices.spec @@ -104,7 +104,7 @@ @ stub WsReadArray @ stub WsReadAttribute @ stdcall WsReadBody(ptr ptr long ptr ptr long ptr) -@ stub WsReadBytes +@ stdcall WsReadBytes(ptr ptr long ptr ptr) @ stub WsReadChars @ stub WsReadCharsUtf8 @ stdcall WsReadElement(ptr ptr long ptr ptr long ptr) diff --git a/include/webservices.h b/include/webservices.h index f1d34c4..3274082 100644 --- a/include/webservices.h +++ b/include/webservices.h @@ -1461,6 +1461,9 @@ HRESULT WINAPI WsReadAttribute(WS_XML_READER*, const WS_ATTRIBUTE_DESCRIPTION*, WS_HEAP*, void*, ULONG, WS_ERROR*); HRESULT WINAPI WsReadBody(WS_MESSAGE*, const WS_ELEMENT_DESCRIPTION*, WS_READ_OPTION, WS_HEAP*, void*, ULONG, WS_ERROR*); +HRESULT WINAPI WsReadBytes(WS_XML_READER*, void*, ULONG, ULONG*, WS_ERROR*); +HRESULT WINAPI WsReadChars(WS_XML_READER*, WCHAR*, ULONG, ULONG*, WS_ERROR*); +HRESULT WINAPI WsReadCharsUtf8(WS_XML_READER*, BYTE*, ULONG, ULONG*, WS_ERROR*); HRESULT WINAPI WsReadElement(WS_XML_READER*, const WS_ELEMENT_DESCRIPTION*, WS_READ_OPTION, WS_HEAP*, void*, ULONG, WS_ERROR*); HRESULT WINAPI WsReadEndAttribute(WS_XML_READER*, WS_ERROR*); -- 2.1.4 From hans at codeweavers.com Tue Oct 25 06:03:19 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Tue, 25 Oct 2016 13:03:19 +0200 Subject: [2/6] webservices: Implement WsReadCharsUtf8. Message-ID: <1477393403-7042-2-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/reader.c | 29 ++++++++++ dlls/webservices/tests/reader.c | 118 ++++++++++++++++++++++++++++++++++++++ dlls/webservices/webservices.spec | 2 +- 3 files changed, 148 insertions(+), 1 deletion(-) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 9a3c7d7..44f8402 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -4582,3 +4582,32 @@ HRESULT WINAPI WsReadBytes( WS_XML_READER *handle, void *bytes, ULONG max_count, return S_OK; } + +/************************************************************************** + * WsReadCharsUtf8 [webservices.@] + */ +HRESULT WINAPI WsReadCharsUtf8( WS_XML_READER *handle, BYTE *bytes, ULONG max_count, ULONG *count, WS_ERROR *error ) +{ + struct reader *reader = (struct reader *)handle; + + TRACE( "%p %p %u %p %p\n", handle, bytes, max_count, count, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!reader) return E_INVALIDARG; + if (!reader->input_type) return WS_E_INVALID_OPERATION; + if (!count) return E_INVALIDARG; + + *count = 0; + if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && bytes) + { + const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)reader->current; + const WS_XML_UTF8_TEXT *utf8 = (const WS_XML_UTF8_TEXT *)text->text; + + if (reader->text_conv_offset == utf8->value.length) return read_node( reader ); + *count = min( utf8->value.length - reader->text_conv_offset, max_count ); + memcpy( bytes, utf8->value.bytes + reader->text_conv_offset, *count ); + reader->text_conv_offset += *count; + } + + return S_OK; +} diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index c804105..330eb00 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -3978,6 +3978,123 @@ static void test_WsReadBytes(void) WsFreeReader( reader ); } +static void test_WsReadCharsUtf8(void) +{ + HRESULT hr; + WS_XML_READER *reader; + const WS_XML_NODE *node; + const WS_XML_TEXT_NODE *text; + const WS_XML_UTF8_TEXT *utf8; + BYTE buf[4]; + ULONG count; + + hr = WsCreateReader( NULL, 0, &reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadCharsUtf8( NULL, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsReadCharsUtf8( reader, NULL, 0, NULL, NULL ); + ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr ); + + hr = set_input( reader, "text", sizeof("text") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadCharsUtf8( reader, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = set_input( reader, "text", sizeof("text") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadCharsUtf8( reader, buf, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = set_input( reader, "text", sizeof("text") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + count = 0xdeadbeef; + hr = WsReadCharsUtf8( reader, NULL, 0, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + count = 0xdeadbeef; + hr = WsReadCharsUtf8( reader, NULL, 1, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadCharsUtf8( reader, buf, 0, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + ok( !buf[0], "wrong data\n" ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + ok( !buf[0], "wrong data\n" ); + + hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + ok( !buf[0], "wrong data\n" ); + + hr = WsReadStartElement( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + count = 0xdeadbeef; + hr = WsReadCharsUtf8( reader, NULL, 0, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 2, "got %u\n", count ); + ok( !memcmp( buf, "te", 2 ), "wrong data\n" ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + text = (const WS_XML_TEXT_NODE *)node; + ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType ); + utf8 = (const WS_XML_UTF8_TEXT *)text->text; + ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType ); + ok( utf8->value.length == 4, "got %u\n", utf8->value.length ); + ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 2, "got %u\n", count ); + ok( !memcmp( buf, "xt", 2 ), "wrong data\n" ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + text = (const WS_XML_TEXT_NODE *)node; + ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType ); + + count = 0xdeadbeef; + hr = WsReadCharsUtf8( reader, buf, 1, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + text = (const WS_XML_TEXT_NODE *)node; + ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType ); + + WsFreeReader( reader ); +} + START_TEST(reader) { test_WsCreateError(); @@ -4015,4 +4132,5 @@ START_TEST(reader) test_entities(); test_field_options(); test_WsReadBytes(); + test_WsReadCharsUtf8(); } diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec index 26db0b2..e785497 100644 --- a/dlls/webservices/webservices.spec +++ b/dlls/webservices/webservices.spec @@ -106,7 +106,7 @@ @ stdcall WsReadBody(ptr ptr long ptr ptr long ptr) @ stdcall WsReadBytes(ptr ptr long ptr ptr) @ stub WsReadChars -@ stub WsReadCharsUtf8 +@ stdcall WsReadCharsUtf8(ptr ptr long ptr ptr) @ stdcall WsReadElement(ptr ptr long ptr ptr long ptr) @ stdcall WsReadEndAttribute(ptr ptr) @ stdcall WsReadEndElement(ptr ptr) -- 2.1.4 From hans at codeweavers.com Tue Oct 25 06:03:20 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Tue, 25 Oct 2016 13:03:20 +0200 Subject: [3/6] webservices: Implement WsReadChars. Message-ID: <1477393403-7042-3-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/reader.c | 45 ++++++++++++++ dlls/webservices/tests/reader.c | 121 ++++++++++++++++++++++++++++++++++++++ dlls/webservices/webservices.spec | 2 +- 3 files changed, 167 insertions(+), 1 deletion(-) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 44f8402..7996cbe 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -4583,6 +4583,51 @@ HRESULT WINAPI WsReadBytes( WS_XML_READER *handle, void *bytes, ULONG max_count, return S_OK; } +static HRESULT utf8_to_utf16( const WS_XML_UTF8_TEXT *utf8, WS_XML_UTF16_TEXT *utf16 ) +{ + int len = MultiByteToWideChar( CP_UTF8, 0, (char *)utf8->value.bytes, utf8->value.length, NULL, 0 ); + if (!(utf16->bytes = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY; + MultiByteToWideChar( CP_UTF8, 0, (char *)utf8->value.bytes, utf8->value.length, (WCHAR *)utf16->bytes, len ); + utf16->byteCount = len * sizeof(WCHAR); + return S_OK; +} + +/************************************************************************** + * WsReadChars [webservices.@] + */ +HRESULT WINAPI WsReadChars( WS_XML_READER *handle, WCHAR *chars, ULONG max_count, ULONG *count, WS_ERROR *error ) +{ + struct reader *reader = (struct reader *)handle; + + TRACE( "%p %p %u %p %p\n", handle, chars, max_count, count, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!reader) return E_INVALIDARG; + if (!reader->input_type) return WS_E_INVALID_OPERATION; + if (!count) return E_INVALIDARG; + + *count = 0; + if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && chars) + { + const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)reader->current; + WS_XML_UTF16_TEXT utf16; + HRESULT hr; + + if ((hr = utf8_to_utf16( (const WS_XML_UTF8_TEXT *)text->text, &utf16 )) != S_OK) return hr; + if (reader->text_conv_offset == utf16.byteCount / sizeof(WCHAR)) + { + heap_free( utf16.bytes ); + return read_node( reader ); + } + *count = min( utf16.byteCount / sizeof(WCHAR) - reader->text_conv_offset, max_count ); + memcpy( chars, utf16.bytes + reader->text_conv_offset * sizeof(WCHAR), *count * sizeof(WCHAR) ); + reader->text_conv_offset += *count; + heap_free( utf16.bytes ); + } + + return S_OK; +} + /************************************************************************** * WsReadCharsUtf8 [webservices.@] */ diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index 330eb00..23c3f10 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -3978,6 +3978,126 @@ static void test_WsReadBytes(void) WsFreeReader( reader ); } +static void test_WsReadChars(void) +{ + static const WCHAR textW[] = {'t','e','x','t'}; + HRESULT hr; + WS_XML_READER *reader; + const WS_XML_NODE *node; + const WS_XML_TEXT_NODE *text; + const WS_XML_UTF8_TEXT *utf8; + unsigned char buf[4]; + WCHAR bufW[4]; + ULONG count; + + hr = WsCreateReader( NULL, 0, &reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadChars( NULL, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsReadChars( reader, NULL, 0, NULL, NULL ); + ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr ); + + hr = set_input( reader, "text", sizeof("text") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadChars( reader, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = set_input( reader, "text", sizeof("text") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadChars( reader, bufW, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = set_input( reader, "text", sizeof("text") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + count = 0xdeadbeef; + hr = WsReadChars( reader, NULL, 0, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + count = 0xdeadbeef; + hr = WsReadChars( reader, NULL, 1, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadChars( reader, bufW, 0, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + ok( !buf[0], "wrong data\n" ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadChars( reader, bufW, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + ok( !buf[0], "wrong data\n" ); + + hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadChars( reader, bufW, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + ok( !buf[0], "wrong data\n" ); + + hr = WsReadStartElement( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + count = 0xdeadbeef; + hr = WsReadChars( reader, NULL, 0, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadChars( reader, bufW, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 2, "got %u\n", count ); + ok( !memcmp( bufW, textW, 2 * sizeof(WCHAR) ), "wrong data\n" ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + text = (const WS_XML_TEXT_NODE *)node; + ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType ); + utf8 = (const WS_XML_UTF8_TEXT *)text->text; + ok( text->text->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", text->text->textType ); + ok( utf8->value.length == 4, "got %u\n", utf8->value.length ); + ok( !memcmp( utf8->value.bytes, "text", 4 ), "wrong data\n" ); + + /* continue reading in a different encoding */ + buf[0] = 0; + count = 0xdeadbeef; + hr = WsReadCharsUtf8( reader, buf, 2, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 2, "got %u\n", count ); + ok( !memcmp( buf, "xt", 2 ), "wrong data\n" ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + text = (const WS_XML_TEXT_NODE *)node; + ok( text->node.nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", text->node.nodeType ); + + count = 0xdeadbeef; + hr = WsReadCharsUtf8( reader, buf, 1, &count, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + text = (const WS_XML_TEXT_NODE *)node; + ok( text->node.nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", text->node.nodeType ); + + WsFreeReader( reader ); +} + static void test_WsReadCharsUtf8(void) { HRESULT hr; @@ -4132,5 +4252,6 @@ START_TEST(reader) test_entities(); test_field_options(); test_WsReadBytes(); + test_WsReadChars(); test_WsReadCharsUtf8(); } diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec index e785497..074f612 100644 --- a/dlls/webservices/webservices.spec +++ b/dlls/webservices/webservices.spec @@ -105,7 +105,7 @@ @ stub WsReadAttribute @ stdcall WsReadBody(ptr ptr long ptr ptr long ptr) @ stdcall WsReadBytes(ptr ptr long ptr ptr) -@ stub WsReadChars +@ stdcall WsReadChars(ptr ptr long ptr ptr) @ stdcall WsReadCharsUtf8(ptr ptr long ptr ptr) @ stdcall WsReadElement(ptr ptr long ptr ptr long ptr) @ stdcall WsReadEndAttribute(ptr ptr) -- 2.1.4 From hans at codeweavers.com Tue Oct 25 06:03:21 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Tue, 25 Oct 2016 13:03:21 +0200 Subject: [4/6] webservices: Add a stub implementation of WS_TYPE_ATTRIBUTE_FIELD_MAPPING in the reader. Message-ID: <1477393403-7042-4-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/reader.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 7996cbe..169a0e1 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -3791,6 +3791,9 @@ ULONG get_type_size( WS_TYPE type, const WS_STRUCT_DESCRIPTION *desc ) case WS_STRUCT_TYPE: return desc->size; + case WS_DESCRIPTION_TYPE: + return sizeof(WS_STRUCT_DESCRIPTION *); + default: ERR( "unhandled type %u\n", type ); return 0; @@ -3829,6 +3832,7 @@ static WS_READ_OPTION get_field_read_option( WS_TYPE type, ULONG options ) return WS_READ_REQUIRED_VALUE; case WS_WSZ_TYPE: + case WS_DESCRIPTION_TYPE: if (options & WS_FIELD_NILLABLE) return WS_READ_NILLABLE_POINTER; if (options & WS_FIELD_OPTIONAL) return WS_READ_OPTIONAL_POINTER; return WS_READ_REQUIRED_POINTER; @@ -3940,6 +3944,10 @@ static HRESULT read_type_struct_field( struct reader *reader, const WS_FIELD_DES ptr = buf + desc->offset; switch (desc->mapping) { + case WS_TYPE_ATTRIBUTE_FIELD_MAPPING: + FIXME( "WS_TYPE_ATTRIBUTE_FIELD_MAPPING not supported\n" ); + return S_OK; + case WS_ATTRIBUTE_FIELD_MAPPING: hr = read_type( reader, WS_ATTRIBUTE_TYPE_MAPPING, desc->type, desc->localName, desc->ns, desc->typeDescription, option, heap, ptr, size ); -- 2.1.4 From hans at codeweavers.com Tue Oct 25 06:03:22 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Tue, 25 Oct 2016 13:03:22 +0200 Subject: [5/6] webservices: Explicitly pass the offset to read_type_struct_field. Message-ID: <1477393403-7042-5-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/reader.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 169a0e1..9994798 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -3921,7 +3921,7 @@ static HRESULT read_type_text( struct reader *reader, const WS_FIELD_DESCRIPTION } static HRESULT read_type_struct_field( struct reader *reader, const WS_FIELD_DESCRIPTION *desc, - WS_HEAP *heap, char *buf ) + WS_HEAP *heap, char *buf, ULONG offset ) { char *ptr; WS_READ_OPTION option; @@ -3941,7 +3941,7 @@ static HRESULT read_type_struct_field( struct reader *reader, const WS_FIELD_DES else size = sizeof(void *); - ptr = buf + desc->offset; + ptr = buf + offset; switch (desc->mapping) { case WS_TYPE_ATTRIBUTE_FIELD_MAPPING: @@ -4005,7 +4005,7 @@ static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_STRUCT_DESCRIPTION *desc, WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size ) { - ULONG i; + ULONG i, offset; HRESULT hr; char *buf; @@ -4038,7 +4038,8 @@ static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping, for (i = 0; i < desc->fieldCount; i++) { - if ((hr = read_type_struct_field( reader, desc->fields[i], heap, buf )) != S_OK) + offset = desc->fields[i]->offset; + if ((hr = read_type_struct_field( reader, desc->fields[i], heap, buf, offset )) != S_OK) break; } -- 2.1.4 From hans at codeweavers.com Tue Oct 25 06:03:23 2016 From: hans at codeweavers.com (Hans Leidekker) Date: Tue, 25 Oct 2016 13:03:23 +0200 Subject: [6/6] webservices: Implement WsCall. Message-ID: <1477393403-7042-6-git-send-email-hans@codeweavers.com> Signed-off-by: Hans Leidekker --- dlls/webservices/msg.c | 78 ++++++++++--- dlls/webservices/proxy.c | 154 +++++++++++++++++++++++- dlls/webservices/reader.c | 104 +++++++++++++++++ dlls/webservices/tests/proxy.c | 208 +++++++++++++++++++++++++++++++++ dlls/webservices/webservices_private.h | 11 ++ dlls/webservices/writer.c | 42 ++++++- 6 files changed, 575 insertions(+), 22 deletions(-) diff --git a/dlls/webservices/msg.c b/dlls/webservices/msg.c index 8f44b40..e7a7969 100644 --- a/dlls/webservices/msg.c +++ b/dlls/webservices/msg.c @@ -64,24 +64,26 @@ struct header struct msg { - WS_MESSAGE_INITIALIZATION init; - WS_MESSAGE_STATE state; - GUID id; - WS_ENVELOPE_VERSION version_env; - WS_ADDRESSING_VERSION version_addr; - BOOL is_addressed; - WS_STRING addr; - WS_STRING action; - WS_HEAP *heap; - WS_XML_BUFFER *buf; - WS_XML_WRITER *writer; - WS_XML_WRITER *writer_body; - WS_XML_READER *reader_body; - ULONG header_count; - ULONG header_size; - struct header **header; - ULONG prop_count; - struct prop prop[sizeof(msg_props)/sizeof(msg_props[0])]; + WS_MESSAGE_INITIALIZATION init; + WS_MESSAGE_STATE state; + GUID id; + WS_ENVELOPE_VERSION version_env; + WS_ADDRESSING_VERSION version_addr; + BOOL is_addressed; + WS_STRING addr; + WS_STRING action; + WS_HEAP *heap; + WS_XML_BUFFER *buf; + WS_XML_WRITER *writer; + WS_XML_WRITER *writer_body; + WS_XML_READER *reader_body; + ULONG header_count; + ULONG header_size; + struct header **header; + WS_PROXY_MESSAGE_CALLBACK_CONTEXT ctx_send; + WS_PROXY_MESSAGE_CALLBACK_CONTEXT ctx_receive; + ULONG prop_count; + struct prop prop[sizeof(msg_props)/sizeof(msg_props[0])]; }; #define HEADER_ARRAY_SIZE 2 @@ -953,7 +955,7 @@ static HRESULT build_mapped_header( const WS_XML_STRING *name, WS_TYPE type, WS_ * WsAddMappedHeader [webservices.@] */ HRESULT WINAPI WsAddMappedHeader( WS_MESSAGE *handle, const WS_XML_STRING *name, WS_TYPE type, - WS_WRITE_OPTION option, const void *value, ULONG size , WS_ERROR *error ) + WS_WRITE_OPTION option, const void *value, ULONG size, WS_ERROR *error ) { struct msg *msg = (struct msg *)handle; struct header *header; @@ -1209,6 +1211,44 @@ HRESULT message_insert_http_headers( WS_MESSAGE *handle, HINTERNET req ) return S_OK; } +void message_set_send_context( WS_MESSAGE *handle, const WS_PROXY_MESSAGE_CALLBACK_CONTEXT *ctx ) +{ + struct msg *msg = (struct msg *)handle; + msg->ctx_send.callback = ctx->callback; + msg->ctx_send.state = ctx->state; +} + +void message_set_receive_context( WS_MESSAGE *handle, const WS_PROXY_MESSAGE_CALLBACK_CONTEXT *ctx ) +{ + struct msg *msg = (struct msg *)handle; + msg->ctx_receive.callback = ctx->callback; + msg->ctx_receive.state = ctx->state; +} + +void message_do_send_callback( WS_MESSAGE *handle ) +{ + struct msg *msg = (struct msg *)handle; + if (msg->ctx_send.callback) + { + HRESULT hr; + TRACE( "executing callback %p\n", msg->ctx_send.callback ); + hr = msg->ctx_send.callback( handle, msg->heap, msg->ctx_send.state, NULL ); + TRACE( "callback %p returned %08x\n", msg->ctx_send.callback, hr ); + } +} + +void message_do_receive_callback( WS_MESSAGE *handle ) +{ + struct msg *msg = (struct msg *)handle; + if (msg->ctx_receive.callback) + { + HRESULT hr; + TRACE( "executing callback %p\n", msg->ctx_receive.callback ); + hr = msg->ctx_receive.callback( handle, msg->heap, msg->ctx_receive.state, NULL ); + TRACE( "callback %p returned %08x\n", msg->ctx_receive.callback, hr ); + } +} + HRESULT message_set_action( WS_MESSAGE *handle, const WS_XML_STRING *action ) { struct msg *msg = (struct msg *)handle; diff --git a/dlls/webservices/proxy.c b/dlls/webservices/proxy.c index 96ac1ad..05214e0 100644 --- a/dlls/webservices/proxy.c +++ b/dlls/webservices/proxy.c @@ -245,6 +245,127 @@ HRESULT WINAPI WsAbortServiceProxy( WS_SERVICE_PROXY *handle, WS_ERROR *error ) return E_NOTIMPL; } +static HRESULT set_send_context( WS_MESSAGE *msg, const WS_CALL_PROPERTY *props, ULONG count ) +{ + ULONG i; + for (i = 0; i < count; i++) + { + if (props[i].id == WS_CALL_PROPERTY_SEND_MESSAGE_CONTEXT) + { + if (props[i].valueSize != sizeof(WS_PROXY_MESSAGE_CALLBACK_CONTEXT)) return E_INVALIDARG; + message_set_send_context( msg, props[i].value ); + break; + } + } + return S_OK; +} + +static HRESULT set_receive_context( WS_MESSAGE *msg, const WS_CALL_PROPERTY *props, ULONG count ) +{ + ULONG i; + for (i = 0; i < count; i++) + { + if (props[i].id == WS_CALL_PROPERTY_RECEIVE_MESSAGE_CONTEXT) + { + if (props[i].valueSize != sizeof(WS_PROXY_MESSAGE_CALLBACK_CONTEXT)) return E_INVALIDARG; + message_set_receive_context( msg, props[i].value ); + break; + } + } + return S_OK; +} + +static HRESULT write_message( WS_MESSAGE *msg, WS_XML_WRITER *writer, const WS_ELEMENT_DESCRIPTION *desc, + const WS_PARAMETER_DESCRIPTION *params, ULONG count, const void **args ) +{ + HRESULT hr; + message_do_send_callback( msg ); + if ((hr = WsWriteEnvelopeStart( msg, writer, NULL, NULL, NULL )) != S_OK) return hr; + if ((hr = write_input_params( writer, desc, params, count, args )) != S_OK) return hr; + return WsWriteEnvelopeEnd( msg, NULL ); +} + +static HRESULT send_message( WS_CHANNEL *channel, WS_MESSAGE *msg, WS_MESSAGE_DESCRIPTION *desc, + WS_PARAMETER_DESCRIPTION *params, ULONG count, const void **args ) +{ + WS_XML_WRITER *writer; + HRESULT hr; + + if ((hr = message_set_action( msg, desc->action )) != S_OK) return hr; + if ((hr = WsCreateWriter( NULL, 0, &writer, NULL )) != S_OK) return hr; + if ((hr = set_output( writer )) != S_OK) goto done; + if ((hr = write_message( msg, writer, desc->bodyElementDescription, params, count, args )) != S_OK) goto done; + hr = channel_send_message( channel, msg ); + +done: + WsFreeWriter( writer ); + return hr; +} + +static HRESULT read_message( WS_MESSAGE *msg, WS_XML_READER *reader, WS_HEAP *heap, + const WS_ELEMENT_DESCRIPTION *desc, const WS_PARAMETER_DESCRIPTION *params, + ULONG count, const void **args ) +{ + HRESULT hr; + if ((hr = WsReadEnvelopeStart( msg, reader, NULL, NULL, NULL )) != S_OK) return hr; + message_do_receive_callback( msg ); + if ((hr = read_output_params( reader, heap, desc, params, count, args )) != S_OK) return hr; + return WsReadEnvelopeEnd( msg, NULL ); +} + +static HRESULT receive_message( WS_CHANNEL *channel, WS_MESSAGE *msg, WS_MESSAGE_DESCRIPTION *desc, + WS_PARAMETER_DESCRIPTION *params, ULONG count, WS_HEAP *heap, const void **args ) +{ + WS_XML_READER *reader; + char *buf; + ULONG len; + HRESULT hr; + + if ((hr = message_set_action( msg, desc->action )) != S_OK) return hr; + if ((hr = channel_receive_message( channel, &buf, &len )) != S_OK) return hr; + if ((hr = WsCreateReader( NULL, 0, &reader, NULL )) != S_OK) goto done; + if ((hr = set_input( reader, buf, len )) != S_OK) goto done; + hr = read_message( msg, reader, heap, desc->bodyElementDescription, params, count, args ); + +done: + WsFreeReader( reader ); + heap_free( buf); + return hr; +} + +static HRESULT create_input_message( WS_CHANNEL *channel, const WS_CALL_PROPERTY *properties, + ULONG count, WS_MESSAGE **ret ) +{ + WS_MESSAGE *msg; + HRESULT hr; + + if ((hr = WsCreateMessageForChannel( channel, NULL, 0, &msg, NULL )) != S_OK) return hr; + if ((hr = WsInitializeMessage( msg, WS_REQUEST_MESSAGE, NULL, NULL )) != S_OK || + (hr = set_send_context( msg, properties, count )) != S_OK) + { + WsFreeMessage( msg ); + return hr; + } + *ret = msg; + return S_OK; +} + +static HRESULT create_output_message( WS_CHANNEL *channel, const WS_CALL_PROPERTY *properties, + ULONG count, WS_MESSAGE **ret ) +{ + WS_MESSAGE *msg; + HRESULT hr; + + if ((hr = WsCreateMessageForChannel( channel, NULL, 0, &msg, NULL )) != S_OK) return hr; + if ((hr = set_receive_context( msg, properties, count )) != S_OK) + { + WsFreeMessage( msg ); + return hr; + } + *ret = msg; + return S_OK; +} + /************************************************************************** * WsCall [webservices.@] */ @@ -252,6 +373,35 @@ HRESULT WINAPI WsCall( WS_SERVICE_PROXY *handle, const WS_OPERATION_DESCRIPTION WS_HEAP *heap, const WS_CALL_PROPERTY *properties, const ULONG count, const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error ) { - FIXME( "%p %p %p %p %p %u %p %p\n", handle, desc, args, heap, properties, count, ctx, error ); - return E_NOTIMPL; + struct proxy *proxy = (struct proxy *)handle; + WS_MESSAGE *msg; + HRESULT hr; + ULONG i; + + TRACE( "%p %p %p %p %p %u %p %p\n", handle, desc, args, heap, properties, count, ctx, error ); + if (error) FIXME( "ignoring error parameter\n" ); + if (ctx) FIXME( "ignoring ctx parameter\n" ); + for (i = 0; i < count; i++) + { + if (properties[i].id != WS_CALL_PROPERTY_SEND_MESSAGE_CONTEXT && + properties[i].id != WS_CALL_PROPERTY_RECEIVE_MESSAGE_CONTEXT) + { + FIXME( "unimplemented call property %u\n", properties[i].id ); + return E_NOTIMPL; + } + } + + if (!handle || !desc || (desc->parameterCount && !args)) return E_INVALIDARG; + + if ((hr = create_input_message( proxy->channel, properties, count, &msg )) != S_OK) return hr; + hr = send_message( proxy->channel, msg, desc->inputMessageDescription, desc->parameterDescription, + desc->parameterCount, args ); + WsFreeMessage( msg ); + if (hr != S_OK) return hr; + + if ((hr = create_output_message( proxy->channel, properties, count, &msg )) != S_OK) return hr; + hr = receive_message( proxy->channel, msg, desc->outputMessageDescription, desc->parameterDescription, + desc->parameterCount, heap, args ); + WsFreeMessage( msg ); + return hr; } diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 9994798..5b5dc69 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -4665,3 +4665,107 @@ HRESULT WINAPI WsReadCharsUtf8( WS_XML_READER *handle, BYTE *bytes, ULONG max_co return S_OK; } + +HRESULT get_param_desc( const WS_STRUCT_DESCRIPTION *desc, USHORT index, const WS_FIELD_DESCRIPTION **ret ) +{ + if (index >= desc->fieldCount) return E_INVALIDARG; + *ret = desc->fields[index]; + return S_OK; +} + +static ULONG get_field_size( const WS_FIELD_DESCRIPTION *desc ) +{ + WS_READ_OPTION option; + ULONG size; + + switch ((option = get_field_read_option( desc->type, desc->options ))) + { + case WS_READ_REQUIRED_POINTER: + case WS_READ_OPTIONAL_POINTER: + case WS_READ_NILLABLE_POINTER: + size = sizeof(void *); + break; + + case WS_READ_REQUIRED_VALUE: + case WS_READ_NILLABLE_VALUE: + size = get_type_size( desc->type, desc->typeDescription ); + break; + + default: + WARN( "unhandled option %u\n", option ); + return 0; + } + + return size; +} + +static HRESULT read_param( struct reader *reader, const WS_FIELD_DESCRIPTION *desc, WS_HEAP *heap, void *ret ) +{ + if (!ret && !(ret = ws_alloc_zero( heap, get_field_size(desc) ))) return WS_E_QUOTA_EXCEEDED; + return read_type_struct_field( reader, desc, heap, ret, 0 ); +} + +static HRESULT read_param_array( struct reader *reader, const WS_FIELD_DESCRIPTION *desc, WS_HEAP *heap, + void **ret, ULONG *count ) +{ + if (!ret && !(ret = ws_alloc_zero( heap, sizeof(void **) ))) return WS_E_QUOTA_EXCEEDED; + return read_type_repeating_element( reader, desc, heap, ret, count ); +} + +static void set_array_len( const WS_PARAMETER_DESCRIPTION *params, ULONG count, ULONG index, ULONG len, + const void **args ) +{ + ULONG i, *ptr; + for (i = 0; i < count; i++) + { + if (params[i].outputMessageIndex != index || params[i].parameterType != WS_PARAMETER_TYPE_ARRAY_COUNT) + continue; + if ((ptr = *(ULONG **)args[i])) *ptr = len; + break; + } +} + +HRESULT read_output_params( WS_XML_READER *handle, WS_HEAP *heap, const WS_ELEMENT_DESCRIPTION *desc, + const WS_PARAMETER_DESCRIPTION *params, ULONG count, const void **args ) +{ + struct reader *reader = (struct reader *)handle; + const WS_STRUCT_DESCRIPTION *desc_struct; + const WS_FIELD_DESCRIPTION *desc_field; + ULONG i, len; + HRESULT hr; + + if (desc->type != WS_STRUCT_TYPE || !(desc_struct = desc->typeDescription)) return E_INVALIDARG; + + if ((hr = start_mapping( reader, WS_ELEMENT_TYPE_MAPPING, desc->elementLocalName, desc->elementNs )) != S_OK) + return hr; + + for (i = 0; i < count; i++) + { + if (params[i].outputMessageIndex == INVALID_PARAMETER_INDEX) continue; + if (params[i].parameterType == WS_PARAMETER_TYPE_MESSAGES) + { + FIXME( "messages type not supported\n" ); + return E_NOTIMPL; + } + if ((hr = get_param_desc( desc_struct, params[i].outputMessageIndex, &desc_field )) != S_OK) return hr; + if (params[i].parameterType == WS_PARAMETER_TYPE_NORMAL) + { + void *ptr = *(void **)args[i]; + if ((hr = read_param( reader, desc_field, heap, ptr )) != S_OK) return hr; + } + else if (params[i].parameterType == WS_PARAMETER_TYPE_ARRAY) + { + void **ptr = *(void ***)args[i]; + if ((hr = read_param_array( reader, desc_field, heap, ptr, &len )) != S_OK) return hr; + set_array_len( params, count, params[i].outputMessageIndex, len, args ); + } + } + + if (desc_struct->structOptions & WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT) + { + struct node *parent = find_parent( reader ); + parent->flags |= NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT; + } + + return end_mapping( reader, WS_ELEMENT_TYPE_MAPPING ); +} diff --git a/dlls/webservices/tests/proxy.c b/dlls/webservices/tests/proxy.c index fa4348a..f1676cd 100644 --- a/dlls/webservices/tests/proxy.c +++ b/dlls/webservices/tests/proxy.c @@ -249,6 +249,211 @@ static void test_WsReceiveMessage( int port ) WsFreeMessage( msg ); } +static HRESULT create_proxy( int port, WS_SERVICE_PROXY **ret ) +{ + static const WCHAR fmt[] = + {'h','t','t','p',':','/','/','1','2','7','.','0','.','0','.','1',':','%','u','/',0}; + WS_ENVELOPE_VERSION env_version; + WS_ADDRESSING_VERSION addr_version; + WS_CHANNEL_PROPERTY prop[2]; + WS_ENDPOINT_ADDRESS addr; + WS_SERVICE_PROXY *proxy; + WCHAR url[64]; + HRESULT hr; + + env_version = WS_ENVELOPE_VERSION_SOAP_1_1; + prop[0].id = WS_CHANNEL_PROPERTY_ENVELOPE_VERSION; + prop[0].value = &env_version; + prop[0].valueSize = sizeof(env_version); + + addr_version = WS_ADDRESSING_VERSION_TRANSPORT; + prop[1].id = WS_CHANNEL_PROPERTY_ADDRESSING_VERSION; + prop[1].value = &addr_version; + prop[1].valueSize = sizeof(addr_version); + + *ret = NULL; + hr = WsCreateServiceProxy( WS_CHANNEL_TYPE_REQUEST, WS_HTTP_CHANNEL_BINDING, NULL, NULL, + 0, prop, sizeof(prop)/sizeof(prop[0]), &proxy, NULL ); + if (hr != S_OK) return hr; + + addr.url.length = wsprintfW( url, fmt, port ); + addr.url.chars = url; + addr.headers = NULL; + addr.extensions = NULL; + addr.identity = NULL; + hr = WsOpenServiceProxy( proxy, &addr, NULL, NULL ); + if (hr == S_OK) *ret = proxy; + else WsFreeServiceProxy( proxy ); + return hr; +} + +static const char req_test2[] = + "" + "1" + ""; + +static const char resp_test2[] = + "" + "test12" + ""; + +static void test_WsCall( int port ) +{ + static WCHAR testW[] = {'t','e','s','t',0}; + WS_XML_STRING str = {3, (BYTE *)"str"}; + WS_XML_STRING req = {3, (BYTE *)"req"}; + WS_XML_STRING resp = {4, (BYTE *)"resp"}; + WS_XML_STRING req_elem = {9, (BYTE *)"req_test2"}; + WS_XML_STRING resp_elem = {10, (BYTE *)"resp_test2"}; + WS_XML_STRING req_action = {9, (BYTE *)"req_test2"}; + WS_XML_STRING resp_action = {10, (BYTE *)"resp_test2"}; + WS_XML_STRING val = {3, (BYTE *)"val"}; + WS_XML_STRING ns = {2, (BYTE *)"ns"}; + HRESULT hr; + WS_SERVICE_PROXY *proxy; + WS_OPERATION_DESCRIPTION op; + WS_MESSAGE_DESCRIPTION input_msg, output_msg; + WS_ELEMENT_DESCRIPTION input_elem, output_elem; + WS_STRUCT_DESCRIPTION input_struct, output_struct; + WS_FIELD_DESCRIPTION f, f2, f3, *fields[2], *fields2[2]; + WS_PARAMETER_DESCRIPTION param[4]; + const void *args[4]; + WS_HEAP *heap; + INT32 **val_ptr; + WCHAR **str_ptr; + ULONG *count_ptr; + struct input + { + INT32 val; + } in; + struct output + { + WCHAR *str; + ULONG count; + INT32 *val; + } out; + + hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsCall( NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = create_proxy( port, &proxy ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsCall( proxy, NULL, NULL, NULL, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + memset( &f, 0, sizeof(f) ); + f.mapping = WS_ELEMENT_FIELD_MAPPING; + f.localName = &val; + f.ns = &ns; + f.type = WS_INT32_TYPE; + fields[0] = &f; + + memset( &input_struct, 0, sizeof(input_struct) ); + input_struct.size = sizeof(struct input); + input_struct.alignment = TYPE_ALIGNMENT(struct input); + input_struct.fields = fields; + input_struct.fieldCount = 1; + input_struct.typeLocalName = &req; + input_struct.typeNs = &ns; + + input_elem.elementLocalName = &req_elem; + input_elem.elementNs = &ns; + input_elem.type = WS_STRUCT_TYPE; + input_elem.typeDescription = &input_struct; + input_msg.action = &req_action; + input_msg.bodyElementDescription = &input_elem; + + memset( &f2, 0, sizeof(f2) ); + f2.mapping = WS_ELEMENT_FIELD_MAPPING; + f2.localName = &str; + f2.ns = &ns; + f2.type = WS_WSZ_TYPE; + f2.offset = FIELD_OFFSET(struct output, str); + fields2[0] = &f2; + + memset( &f3, 0, sizeof(f3) ); + f3.mapping = WS_REPEATING_ELEMENT_FIELD_MAPPING; + f3.type = WS_INT32_TYPE; + f3.offset = FIELD_OFFSET(struct output, val); + f3.countOffset = FIELD_OFFSET(struct output, count); + f3.itemLocalName = &val; + f3.itemNs = &ns; + fields2[1] = &f3; + + memset( &output_struct, 0, sizeof(output_struct) ); + output_struct.size = sizeof(struct output); + output_struct.alignment = TYPE_ALIGNMENT(struct output); + output_struct.fields = fields2; + output_struct.fieldCount = 2; + output_struct.typeLocalName = &resp; + output_struct.typeNs = &ns; + + output_elem.elementLocalName = &resp_elem; + output_elem.elementNs = &ns; + output_elem.type = WS_STRUCT_TYPE; + output_elem.typeDescription = &output_struct; + output_msg.action = &resp_action; + output_msg.bodyElementDescription = &output_elem; + + param[0].parameterType = WS_PARAMETER_TYPE_NORMAL; + param[0].inputMessageIndex = 0; + param[0].outputMessageIndex = 0xffff; + + param[1].parameterType = WS_PARAMETER_TYPE_NORMAL; + param[1].inputMessageIndex = 0xffff; + param[1].outputMessageIndex = 0; + + param[2].parameterType = WS_PARAMETER_TYPE_ARRAY; + param[2].inputMessageIndex = 0xffff; + param[2].outputMessageIndex = 1; + + param[3].parameterType = WS_PARAMETER_TYPE_ARRAY_COUNT; + param[3].inputMessageIndex = 0xffff; + param[3].outputMessageIndex = 1; + + op.versionInfo = 1; + op.inputMessageDescription = &input_msg; + op.outputMessageDescription = &output_msg; + op.inputMessageOptions = 0; + op.outputMessageOptions = 0; + op.parameterCount = 4; + op.parameterDescription = param; + op.stubCallback = NULL; + op.style = 0; + hr = WsCall( proxy, &op, NULL, NULL, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + in.val = 1; + args[0] = &in.val; + + out.str = NULL; + out.count = 0; + out.val = 0; + str_ptr = &out.str; + val_ptr = &out.val; + count_ptr = &out.count; + args[1] = &str_ptr; + args[2] = &val_ptr; + args[3] = &count_ptr; + + hr = WsCall( proxy, &op, args, heap, NULL, 0, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( out.str, testW ), "wrong data\n" ); + ok( out.count == 2, "got %u\n", out.count ); + ok( out.val[0] == 1, "got %u\n", out.val[0] ); + ok( out.val[1] == 2, "got %u\n", out.val[1] ); + + hr = WsCloseServiceProxy( proxy, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + WsFreeServiceProxy( proxy ); + WsFreeHeap( heap ); +} + static const struct { const char *req_action; @@ -261,6 +466,7 @@ static const struct tests[] = { { "req_test1", req_test1, sizeof(req_test1)-1, "resp_test1", resp_test1, sizeof(resp_test1)-1 }, + { "req_test2", req_test2, sizeof(req_test2)-1, "resp_test2", resp_test2, sizeof(resp_test2)-1 }, }; static void send_response( int c, const char *action, const char *data, unsigned int len ) @@ -349,6 +555,7 @@ static DWORD CALLBACK server_proc( void *arg ) ok( !memcmp( tests[j].req_data, buf, tests[j].req_len ), "%u: unexpected data\n", j ); } send_response( c, tests[j].resp_action, tests[j].resp_data, tests[j].resp_len ); + break; } } @@ -383,6 +590,7 @@ START_TEST(proxy) test_WsSendMessage( info.port, &test1 ); test_WsReceiveMessage( info.port ); + test_WsCall( info.port ); test_WsSendMessage( info.port, &quit ); WaitForSingleObject( thread, 3000 ); diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h index 424f3fe..b442838 100644 --- a/dlls/webservices/webservices_private.h +++ b/dlls/webservices/webservices_private.h @@ -41,6 +41,13 @@ HRESULT set_output( WS_XML_WRITER * ) DECLSPEC_HIDDEN; HRESULT set_input( WS_XML_READER *, char *, ULONG ) DECLSPEC_HIDDEN; ULONG get_type_size( WS_TYPE, const WS_STRUCT_DESCRIPTION * ) DECLSPEC_HIDDEN; +#define INVALID_PARAMETER_INDEX 0xffff +HRESULT get_param_desc( const WS_STRUCT_DESCRIPTION *, USHORT, const WS_FIELD_DESCRIPTION ** ) DECLSPEC_HIDDEN; +HRESULT write_input_params( WS_XML_WRITER *, const WS_ELEMENT_DESCRIPTION *, + const WS_PARAMETER_DESCRIPTION *, ULONG, const void ** ) DECLSPEC_HIDDEN; +HRESULT read_output_params( WS_XML_READER *, WS_HEAP *, const WS_ELEMENT_DESCRIPTION *, + const WS_PARAMETER_DESCRIPTION *, ULONG, const void ** ) DECLSPEC_HIDDEN; + enum node_flag { NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT = 0x1, @@ -100,6 +107,10 @@ HRESULT prop_set( const struct prop *, ULONG, ULONG, const void *, ULONG ) DECLS HRESULT prop_get( const struct prop *, ULONG, ULONG, void *, ULONG ) DECLSPEC_HIDDEN; HRESULT message_set_action( WS_MESSAGE *, const WS_XML_STRING * ) DECLSPEC_HIDDEN; +void message_set_send_context( WS_MESSAGE *, const WS_PROXY_MESSAGE_CALLBACK_CONTEXT * ) DECLSPEC_HIDDEN; +void message_set_receive_context( WS_MESSAGE *, const WS_PROXY_MESSAGE_CALLBACK_CONTEXT * ) DECLSPEC_HIDDEN; +void message_do_send_callback( WS_MESSAGE * ) DECLSPEC_HIDDEN; +void message_do_receive_callback( WS_MESSAGE * ) DECLSPEC_HIDDEN; HRESULT message_insert_http_headers( WS_MESSAGE *, HINTERNET ) DECLSPEC_HIDDEN; HRESULT channel_send_message( WS_CHANNEL *, WS_MESSAGE * ) DECLSPEC_HIDDEN; diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 4622277..7982cef 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -2107,7 +2107,7 @@ static HRESULT write_type_struct( struct writer *writer, WS_TYPE_MAPPING mapping if (!desc) return E_INVALIDARG; if (desc->structOptions) FIXME( "struct options 0x%x not supported\n", desc->structOptions ); - if ((hr = get_value_ptr( option, value, size, desc->size, (const void **)&ptr )) != S_OK) return hr; + if ((hr = get_value_ptr( option, value, size, desc->size, &ptr )) != S_OK) return hr; for (i = 0; i < desc->fieldCount; i++) { @@ -2792,3 +2792,43 @@ HRESULT WINAPI WsCopyNode( WS_XML_WRITER *handle, WS_XML_READER *reader, WS_ERRO writer->current = current; return S_OK; } + +static HRESULT write_param( struct writer *writer, const WS_FIELD_DESCRIPTION *desc, const void *value ) +{ + return write_type_struct_field( writer, desc, value, get_field_size(desc) ); +} + +HRESULT write_input_params( WS_XML_WRITER *handle, const WS_ELEMENT_DESCRIPTION *desc, + const WS_PARAMETER_DESCRIPTION *params, ULONG count, const void **args ) +{ + struct writer *writer = (struct writer *)handle; + const WS_STRUCT_DESCRIPTION *desc_struct; + const WS_FIELD_DESCRIPTION *desc_field; + HRESULT hr; + ULONG i; + + if (desc->type != WS_STRUCT_TYPE || !(desc_struct = desc->typeDescription)) return E_INVALIDARG; + + if ((hr = write_element_node( writer, NULL, desc->elementLocalName, desc->elementNs )) != S_OK) return hr; + + for (i = 0; i < count; i++) + { + if (params[i].inputMessageIndex == INVALID_PARAMETER_INDEX) continue; + if (params[i].parameterType == WS_PARAMETER_TYPE_MESSAGES) + { + FIXME( "messages type not supported\n" ); + return E_NOTIMPL; + } + if ((hr = get_param_desc( desc_struct, params[i].inputMessageIndex, &desc_field )) != S_OK) return hr; + if (params[i].parameterType == WS_PARAMETER_TYPE_NORMAL) + { + if ((hr = write_param( writer, desc_field, args[i] )) != S_OK) return hr; + } + else if (params[i].parameterType == WS_PARAMETER_TYPE_ARRAY) + { + FIXME( "no support for writing array parameters\n" ); + } + } + + return write_endelement_node( writer ); +} -- 2.1.4 From madewokherd at gmail.com Tue Oct 25 11:17:15 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Tue, 25 Oct 2016 11:17:15 -0500 Subject: [PATCH] gdiplus: Fix GdipCreateLineBrushFromRectWithAngle implementation In-Reply-To: <3b0ed926-5b0c-5f1f-6795-2f784e29107d@codeweavers.com> References: <3b0ed926-5b0c-5f1f-6795-2f784e29107d@codeweavers.com> Message-ID: Signed-off-by: Vincent Povirk From andrey.goosev at gmail.com Tue Oct 25 13:23:46 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Tue, 25 Oct 2016 21:23:46 +0300 Subject: api-ms-win-core-psapi-obsolete-l1-1-0: Add dll. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: api-ms-win-core-psapi-obsolete-l1-1-0-Add-dll.patch Type: text/x-patch Size: 4349 bytes Desc: not available URL: From madewokherd at gmail.com Tue Oct 25 15:37:07 2016 From: madewokherd at gmail.com (Vincent Povirk) Date: Tue, 25 Oct 2016 15:37:07 -0500 Subject: [PATCH] wincodecs: Remove stub message for implemented methods In-Reply-To: <20161025051840.15219-1-nsivov@codeweavers.com> References: <20161025051840.15219-1-nsivov@codeweavers.com> Message-ID: Signed-off-by: Vincent Povirk From andrey.goosev at gmail.com Wed Oct 26 05:15:22 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Wed, 26 Oct 2016 13:15:22 +0300 Subject: ext-ms-win-gdi-dc-create-l1-1-1: Add dll. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: ext-ms-win-gdi-dc-create-l1-1-1-Add-dll.patch Type: text/x-patch Size: 3254 bytes Desc: not available URL: From andrey.goosev at gmail.com Wed Oct 26 05:16:27 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Wed, 26 Oct 2016 13:16:27 +0300 Subject: ext-ms-win-ntuser-message-l1-1-1: Add dll. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: ext-ms-win-ntuser-message-l1-1-1-Add-dll.patch Type: text/x-patch Size: 4753 bytes Desc: not available URL: From andrey.goosev at gmail.com Wed Oct 26 05:17:19 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Wed, 26 Oct 2016 13:17:19 +0300 Subject: ext-ms-win-rtcore-ntuser-dpi-l1-1-0: Add dll. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: ext-ms-win-rtcore-ntuser-dpi-l1-1-0-Add-dll.patch Type: text/x-patch Size: 3453 bytes Desc: not available URL: From hverbeet at codeweavers.com Wed Oct 26 07:31:21 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Wed, 26 Oct 2016 14:31:21 +0200 Subject: [PATCH] d3drm: Remove stub messages for implemented methods TRACEs In-Reply-To: <20161025051145.6809-1-nsivov@codeweavers.com> References: <20161025051145.6809-1-nsivov@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Wed Oct 26 08:20:21 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Wed, 26 Oct 2016 15:20:21 +0200 Subject: [PATCH 1/4] d2d1: Implement d2d_transformed_geometry_FillContainsPoint(). Message-ID: <1477488024-7803-1-git-send-email-hverbeet@codeweavers.com> From: Andrew Eikum Signed-off-by: Andrew Eikum Signed-off-by: Henri Verbeet --- dlls/d2d1/geometry.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c index 9fa1783..57dcce2 100644 --- a/dlls/d2d1/geometry.c +++ b/dlls/d2d1/geometry.c @@ -2627,10 +2627,17 @@ static HRESULT STDMETHODCALLTYPE d2d_transformed_geometry_StrokeContainsPoint(ID static HRESULT STDMETHODCALLTYPE d2d_transformed_geometry_FillContainsPoint(ID2D1TransformedGeometry *iface, D2D1_POINT_2F point, const D2D1_MATRIX_3X2_F *transform, float tolerance, BOOL *contains) { - FIXME("iface %p, point {%.8e, %.8e}, transform %p, tolerance %.8e, contains %p stub!\n", + struct d2d_geometry *geometry = impl_from_ID2D1TransformedGeometry(iface); + D2D1_MATRIX_3X2_F g; + + TRACE("iface %p, point {%.8e, %.8e}, transform %p, tolerance %.8e, contains %p.\n", iface, point.x, point.y, transform, tolerance, contains); - return E_NOTIMPL; + g = geometry->transform; + if (transform) + d2d_matrix_multiply(&g, transform); + + return ID2D1Geometry_FillContainsPoint(geometry->u.transformed.src_geometry, point, &g, tolerance, contains); } static HRESULT STDMETHODCALLTYPE d2d_transformed_geometry_CompareWithGeometry(ID2D1TransformedGeometry *iface, -- 2.1.4 From hverbeet at codeweavers.com Wed Oct 26 08:20:22 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Wed, 26 Oct 2016 15:20:22 +0200 Subject: [PATCH 2/4] d2d1: Implement d2d_path_geometry_FillContainsPoint(). Message-ID: <1477488024-7803-2-git-send-email-hverbeet@codeweavers.com> From: Andrew Eikum Signed-off-by: Andrew Eikum Signed-off-by: Henri Verbeet --- dlls/d2d1/d2d1_private.h | 23 +++++++++++++++++++++++ dlls/d2d1/geometry.c | 22 +++++++++++++++++++--- dlls/d2d1/render_target.c | 6 ------ 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index b49fce4..8497ea8 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -357,4 +357,27 @@ static inline void d2d_matrix_multiply(D2D_MATRIX_3X2_F *a, const D2D_MATRIX_3X2 a->_32 = tmp._31 * b->_12 + tmp._32 * b->_22 + b->_32; } +/* Dst must be different from src. */ +static inline BOOL d2d_matrix_invert(D2D_MATRIX_3X2_F *dst, const D2D_MATRIX_3X2_F *src) +{ + float d = src->_11 * src->_22 - src->_21 * src->_12; + + if (d == 0.0f) + return FALSE; + dst->_11 = src->_22 / d; + dst->_21 = -src->_21 / d; + dst->_31 = (src->_21 * src->_32 - src->_31 * src->_22) / d; + dst->_12 = -src->_12 / d; + dst->_22 = src->_11 / d; + dst->_32 = -(src->_11 * src->_32 - src->_31 * src->_12) / d; + + return TRUE; +} + +static inline void d2d_point_transform(D2D1_POINT_2F *dst, const D2D1_MATRIX_3X2_F *matrix, float x, float y) +{ + dst->x = x * matrix->_11 + y * matrix->_21 + matrix->_31; + dst->y = x * matrix->_12 + y * matrix->_22 + matrix->_32; +} + #endif /* __WINE_D2D1_PRIVATE_H */ diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c index 57dcce2..385e171 100644 --- a/dlls/d2d1/geometry.c +++ b/dlls/d2d1/geometry.c @@ -1924,9 +1924,11 @@ static HRESULT STDMETHODCALLTYPE d2d_geometry_sink_Close(ID2D1GeometrySink *ifac } done: - d2d_path_geometry_free_figures(geometry); if (FAILED(hr)) + { + d2d_path_geometry_free_figures(geometry); geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR; + } return hr; } @@ -2112,10 +2114,24 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_StrokeContainsPoint(ID2D1Path static HRESULT STDMETHODCALLTYPE d2d_path_geometry_FillContainsPoint(ID2D1PathGeometry *iface, D2D1_POINT_2F point, const D2D1_MATRIX_3X2_F *transform, float tolerance, BOOL *contains) { - FIXME("iface %p, point {%.8e, %.8e}, transform %p, tolerance %.8e, contains %p stub!\n", + struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry(iface); + D2D1_MATRIX_3X2_F g_i; + + TRACE("iface %p, point {%.8e, %.8e}, transform %p, tolerance %.8e, contains %p.\n", iface, point.x, point.y, transform, tolerance, contains); - return E_NOTIMPL; + if (transform) + { + if (!d2d_matrix_invert(&g_i, transform)) + return D2DERR_UNSUPPORTED_OPERATION; + d2d_point_transform(&point, &g_i, point.x, point.y); + } + + *contains = !!d2d_path_geometry_point_inside(geometry, &point); + + TRACE("-> %#x.\n", *contains); + + return S_OK; } static HRESULT STDMETHODCALLTYPE d2d_path_geometry_CompareWithGeometry(ID2D1PathGeometry *iface, diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index bc31f4d..798dd0d 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -48,12 +48,6 @@ static void d2d_point_set(D2D1_POINT_2F *dst, float x, float y) dst->y = y; } -static void d2d_point_transform(D2D1_POINT_2F *dst, const D2D1_MATRIX_3X2_F *matrix, float x, float y) -{ - dst->x = x * matrix->_11 + y * matrix->_21 + matrix->_31; - dst->y = x * matrix->_12 + y * matrix->_22 + matrix->_32; -} - static void d2d_rect_expand(D2D1_RECT_F *dst, const D2D1_POINT_2F *point) { if (point->x < dst->left) -- 2.1.4 From hverbeet at codeweavers.com Wed Oct 26 08:20:23 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Wed, 26 Oct 2016 15:20:23 +0200 Subject: [PATCH 3/4] d2d1/tests: Add FillContainsPoint() tests. Message-ID: <1477488024-7803-3-git-send-email-hverbeet@codeweavers.com> From: Andrew Eikum Signed-off-by: Andrew Eikum Signed-off-by: Henri Verbeet --- dlls/d2d1/tests/d2d1.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index d9d240c..b49ed7d 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -1313,12 +1313,12 @@ static void test_path_geometry(void) ID3D10Device1 *device; IDXGISurface *surface; ID2D1Factory *factory; + BOOL match, contains; D2D1_COLOR_F color; ULONG refcount; UINT32 count; HWND window; HRESULT hr; - BOOL match; if (!(device = create_device())) { @@ -1537,6 +1537,29 @@ static void test_path_geometry(void) ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr); match = compare_surface(surface, "3aace1b22aae111cb577614fed16e4eb1650dba5"); ok(match, "Surface does not match.\n"); + + /* Edge test. */ + set_point(&point, 94.0f, 620.0f); + contains = TRUE; + hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, point, NULL, 0.0f, &contains); + ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr); + ok(!contains, "Got unexpected contains %#x.\n", contains); + + set_point(&point, 95.0f, 620.0f); + contains = FALSE; + hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, point, NULL, 0.0f, &contains); + ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr); + ok(contains == TRUE, "Got unexpected contains %#x.\n", contains); + + /* With transformation matrix. */ + set_matrix_identity(&matrix); + translate_matrix(&matrix, -10.0f, 0.0f); + set_point(&point, 85.0f, 620.0f); + contains = FALSE; + hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, point, &matrix, 0.0f, &contains); + ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr); + ok(contains == TRUE, "Got unexpected contains %#x.\n", contains); + ID2D1TransformedGeometry_Release(transformed_geometry); ID2D1PathGeometry_Release(geometry); -- 2.1.4 From hverbeet at codeweavers.com Wed Oct 26 08:20:24 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Wed, 26 Oct 2016 15:20:24 +0200 Subject: [PATCH 4/4] wined3d: Get rid of WINED3DFMT_FLAG_GETDC. Message-ID: <1477488024-7803-4-git-send-email-hverbeet@codeweavers.com> Signed-off-by: Henri Verbeet --- dlls/wined3d/wined3d_private.h | 1 - 1 file changed, 1 deletion(-) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 4e7bb88..c56558d 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3637,7 +3637,6 @@ extern enum wined3d_format_id pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN #define WINED3DFMT_FLAG_RENDERTARGET 0x00000010 #define WINED3DFMT_FLAG_FBO_ATTACHABLE 0x00000040 #define WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB 0x00000080 -#define WINED3DFMT_FLAG_GETDC 0x00000100 #define WINED3DFMT_FLAG_FLOAT 0x00000200 #define WINED3DFMT_FLAG_BUMPMAP 0x00000400 #define WINED3DFMT_FLAG_SRGB_READ 0x00000800 -- 2.1.4 From aric at codeweavers.com Wed Oct 26 10:49:41 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 26 Oct 2016 10:49:41 -0500 Subject: [PATCH v4] winebus.sys: Handle device reports for hidraw devices Message-ID: <1a7a456d-ae84-a0a3-9685-26b34b83a525@codeweavers.com> v2: Suggestions from Sebastian Lackner v3: Further suggestions from Sebastian Lackner v4: More suggestions from Sebastian Lackner Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 2 + dlls/winebus.sys/bus_udev.c | 75 +++++++++++++++++++ dlls/winebus.sys/main.c | 173 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 238 insertions(+), 12 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: v4-0001-winebus.sys-Handle-device-reports-for-hidraw-device.txt Type: text/x-patch Size: 12747 bytes Desc: not available URL: From ken at codeweavers.com Wed Oct 26 10:58:35 2016 From: ken at codeweavers.com (Ken Thomases) Date: Wed, 26 Oct 2016 10:58:35 -0500 Subject: [PATCH] winemac: Use min() rather than MIN(), which is not reliably defined. Message-ID: <1477497515-33967-1-git-send-email-ken@codeweavers.com> Signed-off-by: Ken Thomases --- dlls/winemac.drv/clipboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index fc0d60c..d6a8c1f 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -439,7 +439,7 @@ static int bitmap_info_size(const BITMAPINFO *info, WORD coloruse) } else /* assume BITMAPINFOHEADER */ { - colors = MIN(info->bmiHeader.biClrUsed, 256); + colors = min(info->bmiHeader.biClrUsed, 256); if (!colors && (info->bmiHeader.biBitCount <= 8)) colors = 1 << info->bmiHeader.biBitCount; if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3; -- 2.8.2 From sebastian at fds-team.de Wed Oct 26 11:35:04 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Wed, 26 Oct 2016 18:35:04 +0200 Subject: [PATCH v4] winebus.sys: Handle device reports for hidraw devices In-Reply-To: <1a7a456d-ae84-a0a3-9685-26b34b83a525@codeweavers.com> References: <1a7a456d-ae84-a0a3-9685-26b34b83a525@codeweavers.com> Message-ID: <4460f15c-1cb4-10ae-4e97-11340c0508aa@fds-team.de> On 26.10.2016 17:49, Aric Stewart wrote: > > v2: Suggestions from Sebastian Lackner > v3: Further suggestions from Sebastian Lackner > v4: More suggestions from Sebastian Lackner > Signed-off-by: Aric Stewart > --- > dlls/winebus.sys/bus.h | 2 + > dlls/winebus.sys/bus_udev.c | 75 +++++++++++++++++++ > dlls/winebus.sys/main.c | 173 +++++++++++++++++++++++++++++++++++++++++--- > 3 files changed, 238 insertions(+), 12 deletions(-) > Not sure if the last_report handling is sufficient in the long term, but looks good to me as an initial version. Please note that currently memory is leaked for each HID report, but the mistakes seem to be in hidclass (in call_minidriver and hid_device_thread). Signed-off-by: Sebastian Lackner From aric at codeweavers.com Wed Oct 26 12:46:12 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 26 Oct 2016 12:46:12 -0500 Subject: [PATCH v2] hid: implement HidD_SetOutputReport Message-ID: <608789ec-e9bc-f910-612e-0d4922eff457@codeweavers.com> v2: Suggestions from Sebastian Lackner Signed-off-by: Aric Stewart --- dlls/hid/hid.spec | 2 +- dlls/hid/hidd.c | 6 ++++++ dlls/hidclass.sys/device.c | 12 ++++++------ include/ddk/hidsdi.h | 1 + 4 files changed, 14 insertions(+), 7 deletions(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: v2-0001-hid-implement-HidD_SetOutputReport.txt Type: text/x-patch Size: 3492 bytes Desc: not available URL: From sebastian at fds-team.de Wed Oct 26 13:05:10 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Wed, 26 Oct 2016 20:05:10 +0200 Subject: [PATCH v2] hid: implement HidD_SetOutputReport In-Reply-To: <608789ec-e9bc-f910-612e-0d4922eff457@codeweavers.com> References: <608789ec-e9bc-f910-612e-0d4922eff457@codeweavers.com> Message-ID: On 26.10.2016 19:46, Aric Stewart wrote: > > v2: Suggestions from Sebastian Lackner > Signed-off-by: Aric Stewart > --- > dlls/hid/hid.spec | 2 +- > dlls/hid/hidd.c | 6 ++++++ > dlls/hidclass.sys/device.c | 12 ++++++------ > include/ddk/hidsdi.h | 1 + > 4 files changed, 14 insertions(+), 7 deletions(-) > Signed-off-by: Sebastian Lackner From sebastian at fds-team.de Wed Oct 26 14:52:58 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Wed, 26 Oct 2016 21:52:58 +0200 Subject: [1/3] hidclass.sys: Update reportBuffer pointer after reading packet from ringbuffer. Message-ID: Signed-off-by: Sebastian Lackner --- dlls/hidclass.sys/device.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index 45f88eb..9640af2 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -218,6 +218,7 @@ static void HID_Device_processQueue(DEVICE_OBJECT *device) if (buffer_size) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); + packet->reportBuffer = (BYTE *)packet + sizeof(*packet); TRACE_(hid_report)("Processing Request (%i)\n",ptr); if (irpsp->Parameters.Read.Length >= packet->reportBufferLen) { @@ -645,6 +646,7 @@ NTSTATUS WINAPI HID_Device_read(DEVICE_OBJECT *device, IRP *irp) if (buffer_size) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); + packet->reportBuffer = (BYTE *)packet + sizeof(*packet); TRACE_(hid_report)("Got Packet %p %i\n", packet->reportBuffer, packet->reportBufferLen); if (irpsp->Parameters.Read.Length >= packet->reportBufferLen) { -- 2.9.0 From sebastian at fds-team.de Wed Oct 26 14:53:20 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Wed, 26 Oct 2016 21:53:20 +0200 Subject: [2/3] hidclass.sys: Fix memory leak in call_minidriver. Message-ID: Before 54002103763188b5c5b1fd1210ad4cf09ef80bf9, the output buffer was released because UserIosb != NULL. Signed-off-by: Sebastian Lackner --- dlls/hidclass.sys/main.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/dlls/hidclass.sys/main.c b/dlls/hidclass.sys/main.c index f5a60e9..1742cfe 100644 --- a/dlls/hidclass.sys/main.c +++ b/dlls/hidclass.sys/main.c @@ -98,18 +98,10 @@ NTSTATUS call_minidriver(ULONG code, DEVICE_OBJECT *device, void *in_buff, ULONG IRP *irp; IO_STATUS_BLOCK irp_status; NTSTATUS status; - void *buffer = NULL; - HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL); - if (out_size) - { - buffer = HeapAlloc(GetProcessHeap(), 0, out_size); - memcpy(buffer, out_buff, out_size); - } - irp = IoBuildDeviceIoControlRequest(code, device, in_buff, in_size, - buffer, out_size, TRUE, NULL, &irp_status); + out_buff, out_size, TRUE, NULL, &irp_status); IoSetCompletionRoutine(irp, internalComplete, event, TRUE, TRUE, TRUE); status = IoCallDriver(device, irp); @@ -117,7 +109,6 @@ NTSTATUS call_minidriver(ULONG code, DEVICE_OBJECT *device, void *in_buff, ULONG if (status == STATUS_PENDING) WaitForSingleObject(event, INFINITE); - memcpy(out_buff, buffer, out_size); status = irp->IoStatus.u.Status; IoCompleteRequest(irp, IO_NO_INCREMENT ); -- 2.9.0 From sebastian at fds-team.de Wed Oct 26 14:55:10 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Wed, 26 Oct 2016 21:55:10 +0200 Subject: [3/3] hidclass.sys: Fix memory leak in hid_device_thread. Message-ID: Signed-off-by: Sebastian Lackner --- This patch also sets packet->reportBufferLen in the IOCTL_HID_READ_REPORT case. (In case the returned buffer was smaller than expected) dlls/hidclass.sys/device.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index 9640af2..5039e95 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -256,6 +256,7 @@ static DWORD CALLBACK hid_device_thread(void *args) IRP *irp; IO_STATUS_BLOCK irp_status; + HID_XFER_PACKET *packet; DWORD rc; HANDLE events[2]; NTSTATUS ntrc; @@ -264,16 +265,16 @@ static DWORD CALLBACK hid_device_thread(void *args) events[0] = CreateEventA(NULL, TRUE, FALSE, NULL); events[1] = ext->halt_event; + packet = HeapAlloc(GetProcessHeap(), 0, sizeof(*packet) + ext->preparseData->caps.InputReportByteLength); + packet->reportBuffer = (BYTE *)packet + sizeof(*packet); + if (ext->information.Polled) { while(1) { - HID_XFER_PACKET *packet; ResetEvent(events[0]); - packet = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*packet) + ext->preparseData->caps.InputReportByteLength); packet->reportBufferLen = ext->preparseData->caps.InputReportByteLength; - packet->reportBuffer = ((BYTE*)packet) + sizeof(*packet); packet->reportId = 0; irp = IoBuildDeviceIoControlRequest(IOCTL_HID_GET_INPUT_REPORT, @@ -306,22 +307,12 @@ static DWORD CALLBACK hid_device_thread(void *args) { INT exit_now = FALSE; - HID_XFER_PACKET *packet; - packet = HeapAlloc(GetProcessHeap(), 0, sizeof(*packet) + ext->preparseData->caps.InputReportByteLength); - packet->reportBufferLen = ext->preparseData->caps.InputReportByteLength; - packet->reportBuffer = ((BYTE*)packet) + sizeof(*packet); - packet->reportId = 0; - while(1) { - BYTE *buffer; - - buffer = HeapAlloc(GetProcessHeap(), 0, ext->preparseData->caps.InputReportByteLength); - ResetEvent(events[0]); irp = IoBuildDeviceIoControlRequest(IOCTL_HID_READ_REPORT, - device, NULL, 0, buffer, + device, NULL, 0, packet->reportBuffer, ext->preparseData->caps.InputReportByteLength, TRUE, NULL, &irp_status); @@ -339,8 +330,8 @@ static DWORD CALLBACK hid_device_thread(void *args) if (!exit_now && irp->IoStatus.u.Status == STATUS_SUCCESS) { - packet->reportId = buffer[0]; - memcpy(packet->reportBuffer, buffer, ext->preparseData->caps.InputReportByteLength); + packet->reportBufferLen = irp->IoStatus.Information; + packet->reportId = packet->reportBuffer[0]; RingBuffer_Write(ext->ring_buffer, packet); HID_Device_processQueue(device); } @@ -350,10 +341,9 @@ static DWORD CALLBACK hid_device_thread(void *args) if (exit_now) break; } - - HeapFree(GetProcessHeap(), 0, packet); } + /* FIXME: releasing packet requires IRP cancellation support */ CloseHandle(events[0]); TRACE("Device thread exiting\n"); -- 2.9.0 From aric at codeweavers.com Wed Oct 26 14:58:17 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 26 Oct 2016 14:58:17 -0500 Subject: [PATCH] winebus.sys: Implement IOCTL_HID_SET_OUTPUT_REPORT for hidraw Message-ID: <88f34d71-6f63-3acb-47e8-2f99c9337c1e@codeweavers.com> Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_udev.c | 11 +++++++++++ dlls/winebus.sys/main.c | 10 ++++++++++ 3 files changed, 22 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-winebus.sys-Implement-IOCTL_HID_SET_OUTPUT_REPORT-for-.txt Type: text/x-patch Size: 2490 bytes Desc: not available URL: From aric at codeweavers.com Wed Oct 26 16:08:59 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 26 Oct 2016 16:08:59 -0500 Subject: [1/3] hidclass.sys: Update reportBuffer pointer after reading packet from ringbuffer. In-Reply-To: References: Message-ID: <5ce08e50-b999-8d7b-eb20-d6299cefed94@codeweavers.com> Signed-off-by: Aric Stewart On 10/26/16 2:52 PM, Sebastian Lackner wrote: > Signed-off-by: Sebastian Lackner > --- > dlls/hidclass.sys/device.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c > index 45f88eb..9640af2 100644 > --- a/dlls/hidclass.sys/device.c > +++ b/dlls/hidclass.sys/device.c > @@ -218,6 +218,7 @@ static void HID_Device_processQueue(DEVICE_OBJECT *device) > if (buffer_size) > { > IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); > + packet->reportBuffer = (BYTE *)packet + sizeof(*packet); > TRACE_(hid_report)("Processing Request (%i)\n",ptr); > if (irpsp->Parameters.Read.Length >= packet->reportBufferLen) > { > @@ -645,6 +646,7 @@ NTSTATUS WINAPI HID_Device_read(DEVICE_OBJECT *device, IRP *irp) > if (buffer_size) > { > IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); > + packet->reportBuffer = (BYTE *)packet + sizeof(*packet); > TRACE_(hid_report)("Got Packet %p %i\n", packet->reportBuffer, packet->reportBufferLen); > if (irpsp->Parameters.Read.Length >= packet->reportBufferLen) > { > From aric at codeweavers.com Wed Oct 26 16:11:35 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 26 Oct 2016 16:11:35 -0500 Subject: [2/3] hidclass.sys: Fix memory leak in call_minidriver. In-Reply-To: References: Message-ID: <7be76e7a-cf1a-df2a-6056-249bc07db7a9@codeweavers.com> Signed-off-by: Aric Stewart On 10/26/16 2:53 PM, Sebastian Lackner wrote: > Before 54002103763188b5c5b1fd1210ad4cf09ef80bf9, the output buffer > was released because UserIosb != NULL. > > Signed-off-by: Sebastian Lackner > --- > dlls/hidclass.sys/main.c | 11 +---------- > 1 file changed, 1 insertion(+), 10 deletions(-) > > diff --git a/dlls/hidclass.sys/main.c b/dlls/hidclass.sys/main.c > index f5a60e9..1742cfe 100644 > --- a/dlls/hidclass.sys/main.c > +++ b/dlls/hidclass.sys/main.c > @@ -98,18 +98,10 @@ NTSTATUS call_minidriver(ULONG code, DEVICE_OBJECT *device, void *in_buff, ULONG > IRP *irp; > IO_STATUS_BLOCK irp_status; > NTSTATUS status; > - void *buffer = NULL; > - > HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL); > > - if (out_size) > - { > - buffer = HeapAlloc(GetProcessHeap(), 0, out_size); > - memcpy(buffer, out_buff, out_size); > - } > - > irp = IoBuildDeviceIoControlRequest(code, device, in_buff, in_size, > - buffer, out_size, TRUE, NULL, &irp_status); > + out_buff, out_size, TRUE, NULL, &irp_status); > > IoSetCompletionRoutine(irp, internalComplete, event, TRUE, TRUE, TRUE); > status = IoCallDriver(device, irp); > @@ -117,7 +109,6 @@ NTSTATUS call_minidriver(ULONG code, DEVICE_OBJECT *device, void *in_buff, ULONG > if (status == STATUS_PENDING) > WaitForSingleObject(event, INFINITE); > > - memcpy(out_buff, buffer, out_size); > status = irp->IoStatus.u.Status; > > IoCompleteRequest(irp, IO_NO_INCREMENT ); > From aric at codeweavers.com Wed Oct 26 16:15:45 2016 From: aric at codeweavers.com (Aric Stewart) Date: Wed, 26 Oct 2016 16:15:45 -0500 Subject: [3/3] hidclass.sys: Fix memory leak in hid_device_thread. In-Reply-To: References: Message-ID: <3f857c47-cf82-f414-24b4-972eb6e1cda3@codeweavers.com> Signed-off-by: Aric Stewart On 10/26/16 2:55 PM, Sebastian Lackner wrote: > Signed-off-by: Sebastian Lackner > --- > > This patch also sets packet->reportBufferLen in the IOCTL_HID_READ_REPORT case. > (In case the returned buffer was smaller than expected) > > dlls/hidclass.sys/device.c | 26 ++++++++------------------ > 1 file changed, 8 insertions(+), 18 deletions(-) > > diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c > index 9640af2..5039e95 100644 > --- a/dlls/hidclass.sys/device.c > +++ b/dlls/hidclass.sys/device.c > @@ -256,6 +256,7 @@ static DWORD CALLBACK hid_device_thread(void *args) > > IRP *irp; > IO_STATUS_BLOCK irp_status; > + HID_XFER_PACKET *packet; > DWORD rc; > HANDLE events[2]; > NTSTATUS ntrc; > @@ -264,16 +265,16 @@ static DWORD CALLBACK hid_device_thread(void *args) > events[0] = CreateEventA(NULL, TRUE, FALSE, NULL); > events[1] = ext->halt_event; > > + packet = HeapAlloc(GetProcessHeap(), 0, sizeof(*packet) + ext->preparseData->caps.InputReportByteLength); > + packet->reportBuffer = (BYTE *)packet + sizeof(*packet); > + > if (ext->information.Polled) > { > while(1) > { > - HID_XFER_PACKET *packet; > ResetEvent(events[0]); > > - packet = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*packet) + ext->preparseData->caps.InputReportByteLength); > packet->reportBufferLen = ext->preparseData->caps.InputReportByteLength; > - packet->reportBuffer = ((BYTE*)packet) + sizeof(*packet); > packet->reportId = 0; > > irp = IoBuildDeviceIoControlRequest(IOCTL_HID_GET_INPUT_REPORT, > @@ -306,22 +307,12 @@ static DWORD CALLBACK hid_device_thread(void *args) > { > INT exit_now = FALSE; > > - HID_XFER_PACKET *packet; > - packet = HeapAlloc(GetProcessHeap(), 0, sizeof(*packet) + ext->preparseData->caps.InputReportByteLength); > - packet->reportBufferLen = ext->preparseData->caps.InputReportByteLength; > - packet->reportBuffer = ((BYTE*)packet) + sizeof(*packet); > - packet->reportId = 0; > - > while(1) > { > - BYTE *buffer; > - > - buffer = HeapAlloc(GetProcessHeap(), 0, ext->preparseData->caps.InputReportByteLength); > - > ResetEvent(events[0]); > > irp = IoBuildDeviceIoControlRequest(IOCTL_HID_READ_REPORT, > - device, NULL, 0, buffer, > + device, NULL, 0, packet->reportBuffer, > ext->preparseData->caps.InputReportByteLength, TRUE, NULL, > &irp_status); > > @@ -339,8 +330,8 @@ static DWORD CALLBACK hid_device_thread(void *args) > > if (!exit_now && irp->IoStatus.u.Status == STATUS_SUCCESS) > { > - packet->reportId = buffer[0]; > - memcpy(packet->reportBuffer, buffer, ext->preparseData->caps.InputReportByteLength); > + packet->reportBufferLen = irp->IoStatus.Information; > + packet->reportId = packet->reportBuffer[0]; > RingBuffer_Write(ext->ring_buffer, packet); > HID_Device_processQueue(device); > } > @@ -350,10 +341,9 @@ static DWORD CALLBACK hid_device_thread(void *args) > if (exit_now) > break; > } > - > - HeapFree(GetProcessHeap(), 0, packet); > } > > + /* FIXME: releasing packet requires IRP cancellation support */ > CloseHandle(events[0]); > > TRACE("Device thread exiting\n"); > From rpisl at seznam.cz Wed Oct 26 17:41:43 2016 From: rpisl at seznam.cz (=?UTF-8?q?Roman=20Pi=C5=A1l?=) Date: Thu, 27 Oct 2016 00:41:43 +0200 Subject: [PATCH 1/2] edit: Test that EM_REPLACESEL works after EM_GETHANDLE. Message-ID: <1477521704-14166-1-git-send-email-rpisl@seznam.cz> Signed-off-by: Roman Pišl --- dlls/user32/tests/edit.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/dlls/user32/tests/edit.c b/dlls/user32/tests/edit.c index b9aa1c9..9d710df 100644 --- a/dlls/user32/tests/edit.c +++ b/dlls/user32/tests/edit.c @@ -875,6 +875,8 @@ static void test_edit_control_3(void) HWND hWnd; HWND hParent; HDC hDC; + HLOCAL hBuf; + char* pBuf; int len, dpi; static const char *str = "this is a long string."; static const char *str2 = "this is a long string.\r\nthis is a long string.\r\nthis is a long string.\r\nthis is a long string."; @@ -1117,6 +1119,25 @@ static void test_edit_control_3(void) ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n"); test_notify(0, 0, 0); + /* EM_REPLACESEL should work after EM_GETHANDLE */ + SendMessageA(hWnd, EM_SETLIMITTEXT, 0, 0); + SendMessageA(hWnd, EM_SETSEL, 0, -1); + hBuf = (HLOCAL)SendMessageA(hWnd, EM_GETHANDLE, 0, 0); + ok(hBuf != NULL, "should get a valid handle\n"); + SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str); + + len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0); + ok(len == lstrlenA(str), "text shouldn't have been truncated\n"); + hBuf = (HLOCAL)SendMessageA(hWnd, EM_GETHANDLE, 0, 0); + ok(hBuf != NULL, "should get a valid handle\n"); + pBuf = (char*)LocalLock(hBuf); + ok(pBuf != NULL, "should get a valid buffer\n"); + if (pBuf) + { + ok(strcmp(str, pBuf) == 0, "strings don't match\n"); + LocalUnlock(pBuf); + } + DestroyWindow(hWnd); } -- 2.7.4 From rpisl at seznam.cz Wed Oct 26 17:41:44 2016 From: rpisl at seznam.cz (=?UTF-8?q?Roman=20Pi=C5=A1l?=) Date: Thu, 27 Oct 2016 00:41:44 +0200 Subject: [PATCH 2/2] edit: Fix crash in EM_REPLACESEL after EM_GETHANDLE. In-Reply-To: <1477521704-14166-1-git-send-email-rpisl@seznam.cz> References: <1477521704-14166-1-git-send-email-rpisl@seznam.cz> Message-ID: <1477521704-14166-2-git-send-email-rpisl@seznam.cz> Fixes bug https://bugs.winehq.org/show_bug.cgi?id=40832. Signed-off-by: Roman Pišl --- dlls/user32/edit.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c index 78d78ea..b3ca9d8 100644 --- a/dlls/user32/edit.c +++ b/dlls/user32/edit.c @@ -149,7 +149,6 @@ typedef struct HLOCAL hloc32W; /* our unicode local memory block */ HLOCAL hloc32A; /* alias for ANSI control receiving EM_GETHANDLE or EM_SETHANDLE */ - HLOCAL hlocapp; /* The text buffer handle belongs to the app */ /* * IME Data */ @@ -1263,8 +1262,6 @@ static inline void text_buffer_changed(EDITSTATE *es) */ static void EDIT_LockBuffer(EDITSTATE *es) { - if (es->hlocapp) return; - if (!es->text) { if(!es->hloc32W) return; @@ -1305,8 +1302,6 @@ static void EDIT_LockBuffer(EDITSTATE *es) */ static void EDIT_UnlockBuffer(EDITSTATE *es, BOOL force) { - if (es->hlocapp) return; - /* Edit window might be already destroyed */ if(!IsWindow(es->hwndSelf)) { @@ -2478,11 +2473,6 @@ static HLOCAL EDIT_EM_GetHandle(EDITSTATE *es) hLocal = es->hloc32A; } - EDIT_UnlockBuffer(es, TRUE); - - /* The text buffer handle belongs to the app */ - es->hlocapp = hLocal; - TRACE("Returning %p, LocalSize() = %ld\n", hLocal, LocalSize(hLocal)); return hLocal; } @@ -2604,6 +2594,12 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, LPCWSTR lpsz_replac if (!EDIT_MakeFit(es, tl - (e - s) + strl)) return; + if (!es->text) + { + ERR("es->text == 0 ... please report\n"); + return; + } + if (e != s) { /* there is something to be deleted */ TRACE("deleting stuff.\n"); @@ -2822,9 +2818,6 @@ static void EDIT_EM_SetHandle(EDITSTATE *es, HLOCAL hloc) es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1; - /* The text buffer handle belongs to the control */ - es->hlocapp = NULL; - EDIT_LockBuffer(es); text_buffer_changed(es); @@ -4607,11 +4600,12 @@ static LRESULT EDIT_WM_NCDestroy(EDITSTATE *es) { LINEDEF *pc, *pp; - /* The app can own the text buffer handle */ - if (es->hloc32W && (es->hloc32W != es->hlocapp)) { + if (es->hloc32W) + { LocalFree(es->hloc32W); } - if (es->hloc32A && (es->hloc32A != es->hlocapp)) { + if (es->hloc32A) + { LocalFree(es->hloc32A); } EDIT_InvalidateUniscribeData(es); -- 2.7.4 From crramirez at gmail.com Wed Oct 26 23:24:48 2016 From: crramirez at gmail.com (Carlos Rafael Ramirez) Date: Wed, 26 Oct 2016 23:24:48 -0500 Subject: cmd: if 'if' condition is not met and cmdList->nextCommand is not null, command should be advanced as well Message-ID: <1477542288-7832-1-git-send-email-crramirez@gmail.com> Fixes https://bugs.winehq.org/show_bug.cgi?id=33636 Tested on Windows 10 and Ubuntu 16.04.1. Signed-off-by: Carlos Rafael Ramirez --- programs/cmd/builtins.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 49c366a..bf72ec9 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1575,6 +1575,13 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd, } if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand; } else { + + if (processThese) { + *cmdList = WCMD_process_commands(*cmdList, TRUE, FALSE); + } else { + *cmdList = (*cmdList)->nextcommand; + } + WINE_TRACE("Found end of this IF statement (next = %p)\n", *cmdList); break; } -- 2.7.4 From leslie_alistair at hotmail.com Thu Oct 27 01:53:27 2016 From: leslie_alistair at hotmail.com (Alistair Leslie-Hughes) Date: Thu, 27 Oct 2016 06:53:27 +0000 Subject: [PATCH 1/2] comdlg32: Stop crash when a path is passed into Open File Dialog Message-ID: From: Bruno Jesus <00cpxxx at gmail.com> Fixes: https://bugs.winehq.org/show_bug.cgi?id=30673 Signed-off-by: Alistair Leslie-Hughes --- dlls/comdlg32/filedlg.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dlls/comdlg32/filedlg.c b/dlls/comdlg32/filedlg.c index 95eacd3..67b3566 100644 --- a/dlls/comdlg32/filedlg.c +++ b/dlls/comdlg32/filedlg.c @@ -1565,10 +1565,16 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd) result = GetFullPathNameW(fodInfos->filename, MAX_PATH, tmpBuf, &nameBit); if (result) { - /* nameBit is always shorter than the original filename */ - lstrcpyW(fodInfos->filename,nameBit); + /* nameBit is always shorter than the original filename. It may be NULL + * when the filename contains only a drive name instead of file name */ + if (nameBit) + { + lstrcpyW(fodInfos->filename,nameBit); + *nameBit = 0x00; + } + else + *fodInfos->filename = '\0'; - *nameBit = 0x00; MemFree(fodInfos->initdir); fodInfos->initdir = MemAlloc((lstrlenW(tmpBuf) + 1)*sizeof(WCHAR)); lstrcpyW(fodInfos->initdir, tmpBuf); -- 1.9.1 From leslie_alistair at hotmail.com Thu Oct 27 01:53:39 2016 From: leslie_alistair at hotmail.com (Alistair Leslie-Hughes) Date: Thu, 27 Oct 2016 06:53:39 +0000 Subject: [PATCH 2/2] comdlg32/tests: Test when a directory is passed to OpenFileName Dialog. In-Reply-To: <20161027065304.2225-1-leslie_alistair@hotmail.com> References: <20161027065304.2225-1-leslie_alistair@hotmail.com> Message-ID: Signed-off-by: Alistair Leslie-Hughes --- dlls/comdlg32/tests/filedlg.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/dlls/comdlg32/tests/filedlg.c b/dlls/comdlg32/tests/filedlg.c index 0fe2d84..9270b66 100644 --- a/dlls/comdlg32/tests/filedlg.c +++ b/dlls/comdlg32/tests/filedlg.c @@ -1226,6 +1226,46 @@ static void test_null_filename(void) ok(ofnW.nFileExtension == 0, "ofnW.nFileExtension is 0x%x, should be 0\n", ofnW.nFileExtension); } +static void test_directory_filename(void) +{ + OPENFILENAMEA ofnA = {0}; + OPENFILENAMEW ofnW = {0}; + WCHAR filterW[] = {'t','e','x','t','\0','*','.','t','x','t','\0', + 'A','l','l','\0','*','\0','\0'}; + char szInitialDir[MAX_PATH] = {0}; + WCHAR szInitialDirW[MAX_PATH] = {0}; + DWORD ret; + + GetWindowsDirectoryA(szInitialDir, MAX_PATH); + GetWindowsDirectoryW(szInitialDirW, MAX_PATH); + + szInitialDir[strlen(szInitialDir)] = '\\'; + szInitialDirW[lstrlenW(szInitialDirW)] = '\\'; + + ofnA.lStructSize = OPENFILENAME_SIZE_VERSION_400A; + ofnA.lpstrFile = szInitialDir; + ofnA.nMaxFile = MAX_PATH; + ofnA.lpfnHook = test_null_wndproc; + ofnA.Flags = OFN_ENABLEHOOK | OFN_EXPLORER; + ofnA.hInstance = GetModuleHandleA(NULL); + ofnA.lpstrFilter = "text\0*.txt\0All\0*\0\0"; + ofnA.lpstrDefExt = NULL; + ret = GetOpenFileNameA(&ofnA); + todo_wine ok(!ret, "GetOpenFileNameA returned %#x\n", ret); + + /* unicode tests */ + ofnW.lStructSize = OPENFILENAME_SIZE_VERSION_400W; + ofnW.lpstrFile = szInitialDirW; + ofnW.nMaxFile = MAX_PATH; + ofnW.lpfnHook = test_null_wndproc; + ofnW.Flags = OFN_ENABLEHOOK | OFN_EXPLORER; + ofnW.hInstance = GetModuleHandleW(NULL); + ofnW.lpstrFilter = filterW; + ofnW.lpstrDefExt = NULL; + ret = GetOpenFileNameW(&ofnW); + todo_wine ok(!ret, "GetOpenFileNameW returned %#x\n", ret); +} + START_TEST(filedlg) { test_DialogCancel(); @@ -1239,4 +1279,5 @@ START_TEST(filedlg) if( resizesupported) test_resizable2(); test_extension(); test_null_filename(); + test_directory_filename(); } -- 1.9.1 From andrey.goosev at gmail.com Thu Oct 27 05:23:44 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Thu, 27 Oct 2016 13:23:44 +0300 Subject: ntdll: Forward EtwEventRegister() from EventRegister(). Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: ntdll-Forward-EtwEventRegister-from-EventRegister.patch Type: text/x-patch Size: 938 bytes Desc: not available URL: From aric at codeweavers.com Thu Oct 27 07:13:03 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 27 Oct 2016 07:13:03 -0500 Subject: [PATCH 1/6] winebus.sys: Add OS/X IOHID bus Message-ID: <1b2d4ef9-28c8-b31c-fc80-59215e863071@codeweavers.com> Signed-off-by: Aric Stewart --- dlls/winebus.sys/Makefile.in | 3 +- dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_iohid.c | 161 +++++++++++++++++++++++++++++++++++++++++++ dlls/winebus.sys/main.c | 3 + 4 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 dlls/winebus.sys/bus_iohid.c -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-winebus.sys-Add-OS-X-IOHID-bus.txt Type: text/x-patch Size: 6731 bytes Desc: not available URL: From aric at codeweavers.com Thu Oct 27 07:13:08 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 27 Oct 2016 07:13:08 -0500 Subject: [PATCH 2/6] winebus.sys: Implement adding IOHID devices Message-ID: <6223e3de-0488-e821-f464-d92c18f3b135@codeweavers.com> Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus_iohid.c | 103 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-winebus.sys-Implement-adding-IOHID-devices.txt Type: text/x-patch Size: 4690 bytes Desc: not available URL: From aric at codeweavers.com Thu Oct 27 07:13:11 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 27 Oct 2016 07:13:11 -0500 Subject: [PATCH 3/6] winebus.sys: Implement removing IOHID devices Message-ID: <784a345c-ab20-fa00-95c7-a701fdfdbfe6@codeweavers.com> Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus_iohid.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0003-winebus.sys-Implement-removing-IOHID-devices.txt Type: text/x-patch Size: 1705 bytes Desc: not available URL: From aric at codeweavers.com Thu Oct 27 07:13:15 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 27 Oct 2016 07:13:15 -0500 Subject: [PATCH 4/6] winebus.sys: IOCTL_HID_GET_DEVICE_DESCRIPTOR for iohid Message-ID: <0e7c2b81-e570-3fc0-5a20-059d559a7293@codeweavers.com> Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus_iohid.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0004-winebus.sys-IOCTL_HID_GET_DEVICE_DESCRIPTOR-for-iohid.txt Type: text/x-patch Size: 958 bytes Desc: not available URL: From aric at codeweavers.com Thu Oct 27 07:13:18 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 27 Oct 2016 07:13:18 -0500 Subject: [PATCH 5/6] winebus.sys: IOCTL_HID_GET_STRING for iohid Message-ID: <85bb8f2c-81be-1fd0-dbd0-68630e54c27f@codeweavers.com> Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus_iohid.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0005-winebus.sys-IOCTL_HID_GET_STRING-for-iohid.txt Type: text/x-patch Size: 1384 bytes Desc: not available URL: From aric at codeweavers.com Thu Oct 27 07:13:23 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 27 Oct 2016 07:13:23 -0500 Subject: [PATCH 6/6] winebus.sys: reports for iohid Message-ID: <1117df07-5d62-8252-5ce6-f94c69c9f979@codeweavers.com> Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus_iohid.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0006-winebus.sys-reports-for-iohid.txt Type: text/x-patch Size: 1979 bytes Desc: not available URL: From andrey.goosev at gmail.com Thu Oct 27 08:21:48 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Thu, 27 Oct 2016 16:21:48 +0300 Subject: ntdll: Move EventRegister/Unregister from advapi32 to ntdll. Message-ID: Supersedes 127362 -------------- next part -------------- A non-text attachment was scrubbed... Name: ntdll-Move-EventRegister-Unregister-from-advapi32-to.patch Type: text/x-patch Size: 4155 bytes Desc: not available URL: From aric at codeweavers.com Thu Oct 27 08:37:41 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 27 Oct 2016 08:37:41 -0500 Subject: [PATCH v2] winebus.sys: Implement IOCTL_HID_SET_OUTPUT_REPORT for hidraw Message-ID: v2: Suggestions from Sebastian Lackner Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_udev.c | 18 ++++++++++++++++++ dlls/winebus.sys/main.c | 10 ++++++++++ 3 files changed, 29 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: v2-0001-winebus.sys-Implement-IOCTL_HID_SET_OUTPUT_REPORT-f.txt Type: text/x-patch Size: 2572 bytes Desc: not available URL: From sebastian at fds-team.de Thu Oct 27 09:12:52 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Thu, 27 Oct 2016 16:12:52 +0200 Subject: [PATCH v2] winebus.sys: Implement IOCTL_HID_SET_OUTPUT_REPORT for hidraw In-Reply-To: References: Message-ID: <4fa0e1bb-b81d-20f7-d333-17446ab4f969@fds-team.de> On 27.10.2016 15:37, Aric Stewart wrote: > > v2: Suggestions from Sebastian Lackner > Signed-off-by: Aric Stewart > --- > dlls/winebus.sys/bus.h | 1 + > dlls/winebus.sys/bus_udev.c | 18 ++++++++++++++++++ > dlls/winebus.sys/main.c | 10 ++++++++++ > 3 files changed, 29 insertions(+) > Signed-off-by: Sebastian Lackner From sebastian at fds-team.de Thu Oct 27 09:40:35 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Thu, 27 Oct 2016 16:40:35 +0200 Subject: [1/3] hidclass.sys: Avoid magic constants in ringbuffer implementation. Message-ID: Signed-off-by: Sebastian Lackner --- This should be a noop, but make the code more readable. Currently three ways are used to get/set the pointers: memset, comparison with 0xffffffff, and comparison with -1. dlls/hidclass.sys/buffer.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/dlls/hidclass.sys/buffer.c b/dlls/hidclass.sys/buffer.c index 23636e0..894853d 100644 --- a/dlls/hidclass.sys/buffer.c +++ b/dlls/hidclass.sys/buffer.c @@ -26,6 +26,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(hid); +#define POINTER_UNUSED 0xffffffff #define BASE_BUFFER_SIZE 32 #define MIN_BUFFER_SIZE 2 #define MAX_BUFFER_SIZE 512 @@ -34,7 +35,7 @@ struct ReportRingBuffer { UINT start, end, size; - int *pointers; + UINT *pointers; UINT pointer_alloc; UINT buffer_size; @@ -46,7 +47,10 @@ struct ReportRingBuffer struct ReportRingBuffer* RingBuffer_Create(UINT buffer_size) { struct ReportRingBuffer *ring; + int i; + TRACE("Create Ring Buffer with buffer size %i\n",buffer_size); + ring = HeapAlloc(GetProcessHeap(), 0, sizeof(*ring)); if (!ring) return NULL; @@ -54,13 +58,14 @@ struct ReportRingBuffer* RingBuffer_Create(UINT buffer_size) ring->size = BASE_BUFFER_SIZE; ring->buffer_size = buffer_size; ring->pointer_alloc = 2; - ring->pointers = HeapAlloc(GetProcessHeap(), 0, sizeof(int) * ring->pointer_alloc); + ring->pointers = HeapAlloc(GetProcessHeap(), 0, sizeof(UINT) * ring->pointer_alloc); if (!ring->pointers) { HeapFree(GetProcessHeap(), 0, ring); return NULL; } - memset(ring->pointers, 0xff, sizeof(int) * ring->pointer_alloc); + for (i = 0; i < ring->pointer_alloc; i++) + ring->pointers[i] = POINTER_UNUSED; ring->buffer = HeapAlloc(GetProcessHeap(), 0, buffer_size * ring->size); if (!ring->buffer) { @@ -104,7 +109,7 @@ NTSTATUS RingBuffer_SetSize(struct ReportRingBuffer *ring, UINT size) ring->start = ring->end = 0; for (i = 0; i < ring->pointer_alloc; i++) { - if (ring->pointers[i] != 0xffffffff) + if (ring->pointers[i] != POINTER_UNUSED) ring->pointers[i] = 0; } new_buffer = HeapAlloc(GetProcessHeap(), 0, ring->buffer_size * size); @@ -125,7 +130,7 @@ void RingBuffer_Read(struct ReportRingBuffer *ring, UINT index, void *output, UI void *ret = NULL; EnterCriticalSection(&ring->lock); - if (index >= ring->pointer_alloc || ring->pointers[index] == 0xffffffff) + if (index >= ring->pointer_alloc || ring->pointers[index] == POINTER_UNUSED) { LeaveCriticalSection(&ring->lock); *size = 0; @@ -153,15 +158,15 @@ UINT RingBuffer_AddPointer(struct ReportRingBuffer *ring) UINT idx; EnterCriticalSection(&ring->lock); for (idx = 0; idx < ring->pointer_alloc; idx++) - if (ring->pointers[idx] == -1) + if (ring->pointers[idx] == POINTER_UNUSED) break; if (idx >= ring->pointer_alloc) { int count = idx = ring->pointer_alloc; ring->pointer_alloc *= 2; - ring->pointers = HeapReAlloc(GetProcessHeap(), 0, ring->pointers, sizeof(int) * ring->pointer_alloc); + ring->pointers = HeapReAlloc(GetProcessHeap(), 0, ring->pointers, sizeof(UINT) * ring->pointer_alloc); for( ;count < ring->pointer_alloc; count++) - ring->pointers[count] = -1; + ring->pointers[count] = POINTER_UNUSED; } ring->pointers[idx] = ring->start; LeaveCriticalSection(&ring->lock); @@ -172,7 +177,7 @@ void RingBuffer_RemovePointer(struct ReportRingBuffer *ring, UINT index) { EnterCriticalSection(&ring->lock); if (index < ring->pointer_alloc) - ring->pointers[index] = 0xffffffff; + ring->pointers[index] = POINTER_UNUSED; LeaveCriticalSection(&ring->lock); } -- 2.9.0 From sebastian at fds-team.de Thu Oct 27 09:40:55 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Thu, 27 Oct 2016 16:40:55 +0200 Subject: [2/3] hidclass.sys: Do not return failure when trying to set same ringbuffer size. Message-ID: <193a0112-e748-03e5-d563-d26d9490d46d@fds-team.de> Signed-off-by: Sebastian Lackner --- dlls/hidclass.sys/buffer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dlls/hidclass.sys/buffer.c b/dlls/hidclass.sys/buffer.c index 894853d..14e83e4 100644 --- a/dlls/hidclass.sys/buffer.c +++ b/dlls/hidclass.sys/buffer.c @@ -102,8 +102,10 @@ NTSTATUS RingBuffer_SetSize(struct ReportRingBuffer *ring, UINT size) BYTE* new_buffer; int i; - if (size < MIN_BUFFER_SIZE || size > MAX_BUFFER_SIZE || size == ring->size) + if (size < MIN_BUFFER_SIZE || size > MAX_BUFFER_SIZE) return STATUS_INVALID_PARAMETER; + if (size == ring->size) + return STATUS_SUCCESS; EnterCriticalSection(&ring->lock); ring->start = ring->end = 0; -- 2.9.0 From andrey.goosev at gmail.com Thu Oct 27 09:41:14 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Thu, 27 Oct 2016 17:41:14 +0300 Subject: ntdll: Add ApiSetQueryApiSetPresence stub. Message-ID: From: Michael Müller -------------- next part -------------- A non-text attachment was scrubbed... Name: ntdll-Add-ApiSetQueryApiSetPresence-stub.patch Type: text/x-patch Size: 2278 bytes Desc: not available URL: From sebastian at fds-team.de Thu Oct 27 09:45:00 2016 From: sebastian at fds-team.de (Sebastian Lackner) Date: Thu, 27 Oct 2016 16:45:00 +0200 Subject: [3/3] hidclass.sys: Only return new reports when reading data from ringbuffer. Message-ID: Signed-off-by: Sebastian Lackner --- Depending on the buffer size, we might get a huge amount of old reports otherwise. @ Aric: I believe there are some more things wrong with the ringbuffer implementation. We shouldn't really need a ->start pointer, this is exactly what the ring->pointers[] are used for. Also, the current implementation never uses all slots. dlls/hidclass.sys/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/hidclass.sys/buffer.c b/dlls/hidclass.sys/buffer.c index 14e83e4..0b29f97 100644 --- a/dlls/hidclass.sys/buffer.c +++ b/dlls/hidclass.sys/buffer.c @@ -170,7 +170,7 @@ UINT RingBuffer_AddPointer(struct ReportRingBuffer *ring) for( ;count < ring->pointer_alloc; count++) ring->pointers[count] = POINTER_UNUSED; } - ring->pointers[idx] = ring->start; + ring->pointers[idx] = ring->end; LeaveCriticalSection(&ring->lock); return idx; } -- 2.9.0 From jacek at codeweavers.com Thu Oct 27 10:34:53 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Thu, 27 Oct 2016 17:34:53 +0200 Subject: [PATCH 1/2] xmllite: Return success when setting XmlReaderProperty_MultiLanguage property. Message-ID: <351793a2-2c85-35d7-3e0d-f207370a85cf@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/xmllite/reader.c | 4 ++++ dlls/xmllite/tests/reader.c | 15 +++++++++++++++ 2 files changed, 19 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-xmllite-Return-success-when-setting-XmlReaderProperty.diff Type: text/x-patch Size: 1425 bytes Desc: not available URL: From jacek at codeweavers.com Thu Oct 27 10:34:56 2016 From: jacek at codeweavers.com (Jacek Caban) Date: Thu, 27 Oct 2016 17:34:56 +0200 Subject: [PATCH 2/2] xmllite: Return success when setting XmlReaderProperty_MaxElementDepth property. Message-ID: <04500143-a5d5-44f4-d398-4c41ddc066ad@codeweavers.com> Signed-off-by: Jacek Caban --- dlls/xmllite/reader.c | 3 +++ dlls/xmllite/tests/reader.c | 3 +++ 2 files changed, 6 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-xmllite-Return-success-when-setting-XmlReaderProperty.diff Type: text/x-patch Size: 1169 bytes Desc: not available URL: From nsivov at codeweavers.com Thu Oct 27 11:17:24 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Thu, 27 Oct 2016 19:17:24 +0300 Subject: [PATCH] ucrtbase: Added _sopen_dispatch/_wsopen_dispatch Message-ID: <20161027161724.12226-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- .../api-ms-win-crt-stdio-l1-1-0.spec | 4 ++-- dlls/msvcrt/file.c | 24 ++++++++++++++++++++++ dlls/ucrtbase/ucrtbase.spec | 4 ++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec b/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec index 4b8be01..6acd08e 100644 --- a/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec +++ b/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec @@ -87,7 +87,7 @@ @ cdecl _setmaxstdio(long) ucrtbase._setmaxstdio @ cdecl _setmode(long long) ucrtbase._setmode @ varargs _sopen(str long long) ucrtbase._sopen -@ stub _sopen_dispatch +@ cdecl _sopen_dispatch(str long long long ptr long) ucrtbase._sopen_dispatch @ cdecl _sopen_s(ptr str long long long) ucrtbase._sopen_s @ cdecl _tell(long) ucrtbase._tell @ cdecl -ret64 _telli64(long) ucrtbase._telli64 @@ -107,7 +107,7 @@ @ cdecl _wpopen(wstr wstr) ucrtbase._wpopen @ cdecl _write(long ptr long) ucrtbase._write @ varargs _wsopen(wstr long long) ucrtbase._wsopen -@ stub _wsopen_dispatch +@ cdecl _wsopen_dispatch(wstr long long long ptr long) ucrtbase._wsopen_dispatch @ cdecl _wsopen_s(ptr wstr long long long) ucrtbase._wsopen_s @ cdecl _wtempnam(wstr wstr) ucrtbase._wtempnam @ cdecl _wtmpnam(ptr) ucrtbase._wtmpnam diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index 432d5c7..9097598 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -2330,6 +2330,18 @@ int CDECL MSVCRT__wsopen( const MSVCRT_wchar_t *path, int oflags, int shflags, . } /********************************************************************* + * _wsopen_dispatch (UCRTBASE.@) + */ +int CDECL MSVCRT__wsopen_dispatch( const MSVCRT_wchar_t *path, int oflags, int shflags, + int pmode, int *filehandle, int secure) +{ + if (secure) + FIXME("secure argument ignored.\n"); + + return MSVCRT__wsopen_s( filehandle, path, oflags, shflags, pmode ); +} + +/********************************************************************* * _sopen_s (MSVCRT.@) */ int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, int pmode ) @@ -2349,6 +2361,18 @@ int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, i } /********************************************************************* + * _sopen_dispatch (UCRTBASE.@) + */ +int CDECL MSVCRT__sopen_dispatch( const char *path, int oflags, int shflags, + int pmode, int *filehandle, int secure) +{ + if (secure) + FIXME("secure argument ignored.\n"); + + return MSVCRT__sopen_s( filehandle, path, oflags, shflags, pmode ); +} + +/********************************************************************* * _sopen (MSVCRT.@) */ int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... ) diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index f0598ce..47608f9 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -1902,7 +1902,7 @@ @ stub _setsystime(ptr long) @ cdecl _sleep(long) MSVCRT__sleep @ varargs _sopen(str long long) MSVCRT__sopen -@ stub _sopen_dispatch +@ cdecl _sopen_dispatch(str long long long ptr long) MSVCRT__sopen_dispatch @ cdecl _sopen_s(ptr str long long long) MSVCRT__sopen_s @ varargs _spawnl(long str str) @ varargs _spawnle(long str str) @@ -2109,7 +2109,7 @@ @ cdecl _wsearchenv_s(wstr wstr ptr long) MSVCRT__wsearchenv_s @ cdecl _wsetlocale(long wstr) MSVCRT__wsetlocale @ varargs _wsopen(wstr long long) MSVCRT__wsopen -@ stub _wsopen_dispatch +@ cdecl _wsopen_dispatch(wstr long long long ptr long) MSVCRT__wsopen_dispatch @ cdecl _wsopen_s(ptr wstr long long long) MSVCRT__wsopen_s @ varargs _wspawnl(long wstr wstr) @ varargs _wspawnle(long wstr wstr) -- 2.9.3 From andrey.goosev at gmail.com Thu Oct 27 13:04:56 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Thu, 27 Oct 2016 21:04:56 +0300 Subject: ext-ms-win-ntuser-uicontext-ext-l1-1-0: Add dll. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: ext-ms-win-ntuser-uicontext-ext-l1-1-0-Add-dll.patch Type: text/x-patch Size: 6769 bytes Desc: not available URL: From aric at codeweavers.com Thu Oct 27 13:41:54 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 27 Oct 2016 13:41:54 -0500 Subject: [1/3] hidclass.sys: Avoid magic constants in ringbuffer implementation. In-Reply-To: References: Message-ID: <554e3800-13ff-1b1e-f518-bdc577ac0cbb@codeweavers.com> Signed-off-by: Aric Stewart On 10/27/16 9:40 AM, Sebastian Lackner wrote: > Signed-off-by: Sebastian Lackner > --- > > This should be a noop, but make the code more readable. Currently three ways > are used to get/set the pointers: memset, comparison with 0xffffffff, and > comparison with -1. > > dlls/hidclass.sys/buffer.c | 23 ++++++++++++++--------- > 1 file changed, 14 insertions(+), 9 deletions(-) > > diff --git a/dlls/hidclass.sys/buffer.c b/dlls/hidclass.sys/buffer.c > index 23636e0..894853d 100644 > --- a/dlls/hidclass.sys/buffer.c > +++ b/dlls/hidclass.sys/buffer.c > @@ -26,6 +26,7 @@ > > WINE_DEFAULT_DEBUG_CHANNEL(hid); > > +#define POINTER_UNUSED 0xffffffff > #define BASE_BUFFER_SIZE 32 > #define MIN_BUFFER_SIZE 2 > #define MAX_BUFFER_SIZE 512 > @@ -34,7 +35,7 @@ struct ReportRingBuffer > { > UINT start, end, size; > > - int *pointers; > + UINT *pointers; > UINT pointer_alloc; > UINT buffer_size; > > @@ -46,7 +47,10 @@ struct ReportRingBuffer > struct ReportRingBuffer* RingBuffer_Create(UINT buffer_size) > { > struct ReportRingBuffer *ring; > + int i; > + > TRACE("Create Ring Buffer with buffer size %i\n",buffer_size); > + > ring = HeapAlloc(GetProcessHeap(), 0, sizeof(*ring)); > if (!ring) > return NULL; > @@ -54,13 +58,14 @@ struct ReportRingBuffer* RingBuffer_Create(UINT buffer_size) > ring->size = BASE_BUFFER_SIZE; > ring->buffer_size = buffer_size; > ring->pointer_alloc = 2; > - ring->pointers = HeapAlloc(GetProcessHeap(), 0, sizeof(int) * ring->pointer_alloc); > + ring->pointers = HeapAlloc(GetProcessHeap(), 0, sizeof(UINT) * ring->pointer_alloc); > if (!ring->pointers) > { > HeapFree(GetProcessHeap(), 0, ring); > return NULL; > } > - memset(ring->pointers, 0xff, sizeof(int) * ring->pointer_alloc); > + for (i = 0; i < ring->pointer_alloc; i++) > + ring->pointers[i] = POINTER_UNUSED; > ring->buffer = HeapAlloc(GetProcessHeap(), 0, buffer_size * ring->size); > if (!ring->buffer) > { > @@ -104,7 +109,7 @@ NTSTATUS RingBuffer_SetSize(struct ReportRingBuffer *ring, UINT size) > ring->start = ring->end = 0; > for (i = 0; i < ring->pointer_alloc; i++) > { > - if (ring->pointers[i] != 0xffffffff) > + if (ring->pointers[i] != POINTER_UNUSED) > ring->pointers[i] = 0; > } > new_buffer = HeapAlloc(GetProcessHeap(), 0, ring->buffer_size * size); > @@ -125,7 +130,7 @@ void RingBuffer_Read(struct ReportRingBuffer *ring, UINT index, void *output, UI > void *ret = NULL; > > EnterCriticalSection(&ring->lock); > - if (index >= ring->pointer_alloc || ring->pointers[index] == 0xffffffff) > + if (index >= ring->pointer_alloc || ring->pointers[index] == POINTER_UNUSED) > { > LeaveCriticalSection(&ring->lock); > *size = 0; > @@ -153,15 +158,15 @@ UINT RingBuffer_AddPointer(struct ReportRingBuffer *ring) > UINT idx; > EnterCriticalSection(&ring->lock); > for (idx = 0; idx < ring->pointer_alloc; idx++) > - if (ring->pointers[idx] == -1) > + if (ring->pointers[idx] == POINTER_UNUSED) > break; > if (idx >= ring->pointer_alloc) > { > int count = idx = ring->pointer_alloc; > ring->pointer_alloc *= 2; > - ring->pointers = HeapReAlloc(GetProcessHeap(), 0, ring->pointers, sizeof(int) * ring->pointer_alloc); > + ring->pointers = HeapReAlloc(GetProcessHeap(), 0, ring->pointers, sizeof(UINT) * ring->pointer_alloc); > for( ;count < ring->pointer_alloc; count++) > - ring->pointers[count] = -1; > + ring->pointers[count] = POINTER_UNUSED; > } > ring->pointers[idx] = ring->start; > LeaveCriticalSection(&ring->lock); > @@ -172,7 +177,7 @@ void RingBuffer_RemovePointer(struct ReportRingBuffer *ring, UINT index) > { > EnterCriticalSection(&ring->lock); > if (index < ring->pointer_alloc) > - ring->pointers[index] = 0xffffffff; > + ring->pointers[index] = POINTER_UNUSED; > LeaveCriticalSection(&ring->lock); > } > > From aric at codeweavers.com Thu Oct 27 13:44:47 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 27 Oct 2016 13:44:47 -0500 Subject: [2/3] hidclass.sys: Do not return failure when trying to set same ringbuffer size. In-Reply-To: <193a0112-e748-03e5-d563-d26d9490d46d@fds-team.de> References: <193a0112-e748-03e5-d563-d26d9490d46d@fds-team.de> Message-ID: Signed-off-by: Aric Stewart On 10/27/16 9:40 AM, Sebastian Lackner wrote: > Signed-off-by: Sebastian Lackner > --- > dlls/hidclass.sys/buffer.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/dlls/hidclass.sys/buffer.c b/dlls/hidclass.sys/buffer.c > index 894853d..14e83e4 100644 > --- a/dlls/hidclass.sys/buffer.c > +++ b/dlls/hidclass.sys/buffer.c > @@ -102,8 +102,10 @@ NTSTATUS RingBuffer_SetSize(struct ReportRingBuffer *ring, UINT size) > BYTE* new_buffer; > int i; > > - if (size < MIN_BUFFER_SIZE || size > MAX_BUFFER_SIZE || size == ring->size) > + if (size < MIN_BUFFER_SIZE || size > MAX_BUFFER_SIZE) > return STATUS_INVALID_PARAMETER; > + if (size == ring->size) > + return STATUS_SUCCESS; > > EnterCriticalSection(&ring->lock); > ring->start = ring->end = 0; > From aric at codeweavers.com Thu Oct 27 13:49:06 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 27 Oct 2016 13:49:06 -0500 Subject: [3/3] hidclass.sys: Only return new reports when reading data from ringbuffer. In-Reply-To: References: Message-ID: Signed-off-by: Aric Stewart On 10/27/16 9:45 AM, Sebastian Lackner wrote: > Signed-off-by: Sebastian Lackner > --- > > Depending on the buffer size, we might get a huge amount of old reports otherwise. > > @ Aric: I believe there are some more things wrong with the ringbuffer implementation. > We shouldn't really need a ->start pointer, this is exactly what the ring->pointers[] > are used for. Also, the current implementation never uses all slots. > > dlls/hidclass.sys/buffer.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/dlls/hidclass.sys/buffer.c b/dlls/hidclass.sys/buffer.c > index 14e83e4..0b29f97 100644 > --- a/dlls/hidclass.sys/buffer.c > +++ b/dlls/hidclass.sys/buffer.c > @@ -170,7 +170,7 @@ UINT RingBuffer_AddPointer(struct ReportRingBuffer *ring) > for( ;count < ring->pointer_alloc; count++) > ring->pointers[count] = POINTER_UNUSED; > } > - ring->pointers[idx] = ring->start; > + ring->pointers[idx] = ring->end; > LeaveCriticalSection(&ring->lock); > return idx; > } > From aric at codeweavers.com Thu Oct 27 14:50:38 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 27 Oct 2016 14:50:38 -0500 Subject: [PATCH] winebus.sys: Implement IOCTL_HID_GET(SET)_FEATURE for hidraw Message-ID: <7cc0113b-0faa-ad01-c850-6a5b2c7da733@codeweavers.com> Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus.h | 2 ++ dlls/winebus.sys/bus_udev.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ dlls/winebus.sys/main.c | 19 +++++++++++++++++++ 3 files changed, 67 insertions(+) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-winebus.sys-Implement-IOCTL_HID_GET-SET-_FEATURE-for-h.txt Type: text/x-patch Size: 3868 bytes Desc: not available URL: From aric at codeweavers.com Thu Oct 27 20:00:20 2016 From: aric at codeweavers.com (Aric Stewart) Date: Thu, 27 Oct 2016 20:00:20 -0500 Subject: [PATCH] winebus.sys: Remove dead code Message-ID: Coverity 1373717 Signed-off-by: Aric Stewart --- dlls/winebus.sys/bus_udev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-winebus.sys-Remove-dead-code.txt Type: text/x-patch Size: 460 bytes Desc: not available URL: From crramirez at gmail.com Wed Oct 26 23:20:33 2016 From: crramirez at gmail.com (Carlos Rafael Ramirez) Date: Wed, 26 Oct 2016 23:20:33 -0500 Subject: cmd: if 'if' condition is not met and cmdList->nextCommand is not null, command should be advanced as well Message-ID: <1477542033-7783-1-git-send-email-crramirez@gmail.com> Fixes https://bugs.winehq.org/show_bug.cgi?id=33636 Tested on Windows 10 and Ubuntu 16.04.1. Signed-off-by: Carlos Rafael Ramirez --- programs/cmd/builtins.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 49c366a..bf72ec9 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1575,6 +1575,13 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd, } if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand; } else { + + if (processThese) { + *cmdList = WCMD_process_commands(*cmdList, TRUE, FALSE); + } else { + *cmdList = (*cmdList)->nextcommand; + } + WINE_TRACE("Found end of this IF statement (next = %p)\n", *cmdList); break; } -- 2.7.4 From nsivov at codeweavers.com Fri Oct 28 01:51:05 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Fri, 28 Oct 2016 09:51:05 +0300 Subject: [PATCH 1/2] d2d1: Support setting and getting back start and end point for linear gradient brush Message-ID: <20161028065106.11936-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/d2d1/brush.c | 29 +++++++++++++++++++---------- dlls/d2d1/d2d1_private.h | 4 ++++ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c index 38872ea..8725992 100644 --- a/dlls/d2d1/brush.c +++ b/dlls/d2d1/brush.c @@ -423,32 +423,42 @@ static void STDMETHODCALLTYPE d2d_linear_gradient_brush_GetTransform(ID2D1Linear static void STDMETHODCALLTYPE d2d_linear_gradient_brush_SetStartPoint(ID2D1LinearGradientBrush *iface, D2D1_POINT_2F start_point) { - FIXME("iface %p, start_point {%.8e, %.8e} stub!\n", iface, start_point.x, start_point.y); + struct d2d_brush *brush = impl_from_ID2D1LinearGradientBrush(iface); + + TRACE("iface %p, start_point {%.8e, %.8e}.\n", iface, start_point.x, start_point.y); + + brush->u.linear.desc.startPoint = start_point; } static void STDMETHODCALLTYPE d2d_linear_gradient_brush_SetEndPoint(ID2D1LinearGradientBrush *iface, D2D1_POINT_2F end_point) { - FIXME("iface %p, end_point {%.8e, %.8e} stub!\n", iface, end_point.x, end_point.y); + struct d2d_brush *brush = impl_from_ID2D1LinearGradientBrush(iface); + + TRACE("iface %p, end_point {%.8e, %.8e}.\n", iface, end_point.x, end_point.y); + + brush->u.linear.desc.endPoint = end_point; } static D2D1_POINT_2F * STDMETHODCALLTYPE d2d_linear_gradient_brush_GetStartPoint(ID2D1LinearGradientBrush *iface, D2D1_POINT_2F *point) { - FIXME("iface %p, point %p stub!\n", iface, point); + struct d2d_brush *brush = impl_from_ID2D1LinearGradientBrush(iface); + + TRACE("iface %p, point %p.\n", iface, point); - point->x = 0.0f; - point->y = 0.0f; + *point = brush->u.linear.desc.startPoint; return point; } static D2D1_POINT_2F * STDMETHODCALLTYPE d2d_linear_gradient_brush_GetEndPoint(ID2D1LinearGradientBrush *iface, D2D1_POINT_2F *point) { - FIXME("iface %p, point %p stub!\n", iface, point); + struct d2d_brush *brush = impl_from_ID2D1LinearGradientBrush(iface); - point->x = 0.0f; - point->y = 0.0f; + TRACE("iface %p, point %p.\n", iface, point); + + *point = brush->u.linear.desc.endPoint; return point; } @@ -483,10 +493,9 @@ HRESULT d2d_linear_gradient_brush_create(ID2D1Factory *factory, const D2D1_LINEA if (!(*brush = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**brush)))) return E_OUTOFMEMORY; - FIXME("Ignoring brush properties.\n"); - d2d_brush_init(*brush, factory, D2D_BRUSH_TYPE_LINEAR, brush_desc, (ID2D1BrushVtbl *)&d2d_linear_gradient_brush_vtbl); + (*brush)->u.linear.desc = *gradient_brush_desc; TRACE("Created brush %p.\n", *brush); return S_OK; diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 8497ea8..f8c0d45 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -196,6 +196,10 @@ struct d2d_brush D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode; ID3D10SamplerState *sampler_state; } bitmap; + struct + { + D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES desc; + } linear; } u; }; -- 2.9.3 From nsivov at codeweavers.com Fri Oct 28 01:51:06 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Fri, 28 Oct 2016 09:51:06 +0300 Subject: [PATCH 2/2] d2d1: Store gradient stop collection pointer for linear gradient brush In-Reply-To: <20161028065106.11936-1-nsivov@codeweavers.com> References: <20161028065106.11936-1-nsivov@codeweavers.com> Message-ID: <20161028065106.11936-2-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/d2d1/brush.c | 10 ++++++++-- dlls/d2d1/d2d1_private.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c index 8725992..4110b48 100644 --- a/dlls/d2d1/brush.c +++ b/dlls/d2d1/brush.c @@ -373,7 +373,10 @@ static ULONG STDMETHODCALLTYPE d2d_linear_gradient_brush_Release(ID2D1LinearGrad TRACE("%p decreasing refcount to %u.\n", iface, refcount); if (!refcount) + { + ID2D1GradientStopCollection_Release(brush->u.linear.gradient); d2d_brush_destroy(brush); + } return refcount; } @@ -465,9 +468,11 @@ static D2D1_POINT_2F * STDMETHODCALLTYPE d2d_linear_gradient_brush_GetEndPoint(I static void STDMETHODCALLTYPE d2d_linear_gradient_brush_GetGradientStopCollection(ID2D1LinearGradientBrush *iface, ID2D1GradientStopCollection **gradient) { - FIXME("iface %p, gradient %p stub!\n", iface, gradient); + struct d2d_brush *brush = impl_from_ID2D1LinearGradientBrush(iface); + + TRACE("iface %p, gradient %p.\n", iface, gradient); - *gradient = NULL; + ID2D1GradientStopCollection_AddRef(*gradient = brush->u.linear.gradient); } static const struct ID2D1LinearGradientBrushVtbl d2d_linear_gradient_brush_vtbl = @@ -496,6 +501,7 @@ HRESULT d2d_linear_gradient_brush_create(ID2D1Factory *factory, const D2D1_LINEA d2d_brush_init(*brush, factory, D2D_BRUSH_TYPE_LINEAR, brush_desc, (ID2D1BrushVtbl *)&d2d_linear_gradient_brush_vtbl); (*brush)->u.linear.desc = *gradient_brush_desc; + ID2D1GradientStopCollection_AddRef((*brush)->u.linear.gradient = gradient); TRACE("Created brush %p.\n", *brush); return S_OK; diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index f8c0d45..021a703 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -199,6 +199,7 @@ struct d2d_brush struct { D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES desc; + ID2D1GradientStopCollection *gradient; } linear; } u; }; -- 2.9.3 From leslie_alistair at hotmail.com Fri Oct 28 02:06:56 2016 From: leslie_alistair at hotmail.com (Alistair Leslie-Hughes) Date: Fri, 28 Oct 2016 07:06:56 +0000 Subject: [PATCH 1/4] dpnet: Semi-stub IDirectPlay8Peer SetPeerInfo Message-ID: Signed-off-by: Alistair Leslie-Hughes --- dlls/dpnet/address.c | 31 --------------------- dlls/dpnet/dpnet_private.h | 22 +++++++++++++++ dlls/dpnet/peer.c | 48 ++++++++++++++++++++++++++++++-- dlls/dpnet/tests/peer.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 34 deletions(-) diff --git a/dlls/dpnet/address.c b/dlls/dpnet/address.c index 6305fe7..c5457eb 100644 --- a/dlls/dpnet/address.c +++ b/dlls/dpnet/address.c @@ -39,37 +39,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(dpnet); -static inline void *heap_alloc(size_t len) -{ - return HeapAlloc(GetProcessHeap(), 0, len); -} - -static inline void *heap_realloc(void *mem, size_t len) -{ - return HeapReAlloc( GetProcessHeap(), 0, mem, len); -} - -static inline BOOL heap_free(void *mem) -{ - return HeapFree(GetProcessHeap(), 0, mem); -} - -static inline LPWSTR heap_strdupW(LPCWSTR str) -{ - LPWSTR ret = NULL; - - if(str) { - DWORD size; - - size = (strlenW(str)+1)*sizeof(WCHAR); - ret = heap_alloc(size); - if(ret) - memcpy(ret, str, size); - } - - return ret; -} - static char *heap_strdupA( const char *str ) { char *ret; diff --git a/dlls/dpnet/dpnet_private.h b/dlls/dpnet/dpnet_private.h index f9c4400..05608a6 100644 --- a/dlls/dpnet/dpnet_private.h +++ b/dlls/dpnet/dpnet_private.h @@ -26,6 +26,7 @@ #endif #include +#include "wine/unicode.h" #include "dplay8.h" #include "dplobby8.h" @@ -146,6 +147,27 @@ typedef struct { #define FE(x) { x, #x } #define GE(x) { &x, #x } +static inline void *heap_alloc( size_t len ) +{ + return HeapAlloc( GetProcessHeap(), 0, len ); +} + +static inline void *heap_realloc(void *mem, size_t len) +{ + return HeapReAlloc( GetProcessHeap(), 0, mem, len); +} +static inline BOOL heap_free( void *mem ) +{ + return HeapFree( GetProcessHeap(), 0, mem ); +} + +static inline WCHAR *heap_strdupW( const WCHAR *src ) +{ + WCHAR *dst; + if (!src) return NULL; + if ((dst = heap_alloc( (strlenW( src ) + 1) * sizeof(WCHAR) ))) strcpyW( dst, src ); + return dst; +} #endif diff --git a/dlls/dpnet/peer.c b/dlls/dpnet/peer.c index a07a59a..264ca70 100644 --- a/dlls/dpnet/peer.c +++ b/dlls/dpnet/peer.c @@ -48,6 +48,10 @@ typedef struct IDirectPlay8PeerImpl DWORD flags; void *usercontext; + WCHAR *username; + void *data; + DWORD datasize; + DPN_SP_CAPS spcaps; } IDirectPlay8PeerImpl; @@ -92,7 +96,12 @@ static ULONG WINAPI IDirectPlay8PeerImpl_Release(IDirectPlay8Peer *iface) TRACE("(%p) ref=%d\n", This, RefCount); if(!RefCount) - HeapFree(GetProcessHeap(), 0, This); + { + heap_free(This->username); + heap_free(This->data); + + heap_free(This); + } return RefCount; } @@ -310,9 +319,42 @@ static HRESULT WINAPI IDirectPlay8PeerImpl_SetPeerInfo(IDirectPlay8Peer *iface, const DPN_PLAYER_INFO * const pdpnPlayerInfo, void * const pvAsyncContext, DPNHANDLE * const phAsyncHandle, const DWORD dwFlags) { - FIXME("(%p)->(%p,%p,%p,%x): stub\n", iface, pdpnPlayerInfo, pvAsyncContext, phAsyncHandle, dwFlags); + IDirectPlay8PeerImpl* This = impl_from_IDirectPlay8Peer(iface); - return DPNERR_GENERIC; + FIXME("(%p)->(%p,%p,%p,%x) Semi-stub.\n", This, pdpnPlayerInfo, pvAsyncContext, phAsyncHandle, dwFlags); + + if(!pdpnPlayerInfo) + return E_POINTER; + + if(phAsyncHandle) + FIXME("Async handle currently not supported.\n"); + + if (pdpnPlayerInfo->dwInfoFlags & DPNINFO_NAME) + { + heap_free(This->username); + This->username = NULL; + + if(pdpnPlayerInfo->pwszName) + { + This->username = heap_strdupW(pdpnPlayerInfo->pwszName); + if (!This->username) + return E_OUTOFMEMORY; + } + } + + if (pdpnPlayerInfo->dwInfoFlags & DPNINFO_DATA) + { + heap_free(This->data); + + This->datasize = pdpnPlayerInfo->dwDataSize; + This->data = heap_alloc(pdpnPlayerInfo->dwDataSize); + if (!This->data) + return E_OUTOFMEMORY; + + memcpy(This->data, pdpnPlayerInfo->pvData, pdpnPlayerInfo->dwDataSize); + } + + return S_OK; } static HRESULT WINAPI IDirectPlay8PeerImpl_GetPeerInfo(IDirectPlay8Peer *iface, const DPNID dpnid, diff --git a/dlls/dpnet/tests/peer.c b/dlls/dpnet/tests/peer.c index 1fec1f2..f6c413f 100644 --- a/dlls/dpnet/tests/peer.c +++ b/dlls/dpnet/tests/peer.c @@ -212,6 +212,74 @@ static void test_get_sp_caps(void) "expected 0x10000, got 0x%x\n", caps.dwSystemBufferSize); } +static void test_player_info(void) +{ + HRESULT hr; + DPN_PLAYER_INFO info; + WCHAR name[] = {'w','i','n','e',0}; + WCHAR name2[] = {'w','i','n','e','2',0}; + WCHAR data[] = {'X','X','X','X',0}; + + ZeroMemory( &info, sizeof(DPN_PLAYER_INFO) ); + info.dwSize = sizeof(DPN_PLAYER_INFO); + info.dwInfoFlags = DPNINFO_NAME; + + hr = IDirectPlay8Peer_SetPeerInfo(peer, NULL, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == E_POINTER, "got %x\n", hr); + + info.pwszName = NULL; + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.pwszName = name; + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_NAME; + info.pwszName = name2; + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + +if(0) /* Crashes on windows */ +{ + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = NULL; + info.dwDataSize = sizeof(data); + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); +} + + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = data; + info.dwDataSize = 0; + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = data; + info.dwDataSize = sizeof(data); + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA | DPNINFO_NAME; + info.pwszName = name; + info.pvData = data; + info.dwDataSize = sizeof(data); + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + /* Leave PeerInfo with only the name set. */ + info.dwInfoFlags = DPNINFO_DATA | DPNINFO_NAME; + info.pwszName = name; + info.pvData = NULL; + info.dwDataSize = 0; + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); +} + static void test_cleanup_dp(void) { HRESULT hr; @@ -238,5 +306,6 @@ START_TEST(peer) test_enum_service_providers(); test_enum_hosts(); test_get_sp_caps(); + test_player_info(); test_cleanup_dp(); } -- 1.9.1 From leslie_alistair at hotmail.com Fri Oct 28 02:07:07 2016 From: leslie_alistair at hotmail.com (Alistair Leslie-Hughes) Date: Fri, 28 Oct 2016 07:07:07 +0000 Subject: [PATCH 2/4] dpnet: Semi-stub IDirectPlay8Client SetClientInfo In-Reply-To: <20161028070627.16173-1-leslie_alistair@hotmail.com> References: <20161028070627.16173-1-leslie_alistair@hotmail.com> Message-ID: Signed-off-by: Alistair Leslie-Hughes --- dlls/dpnet/client.c | 54 +++++++++++++++++++++++++++++++++---- dlls/dpnet/dpnet_private.h | 3 +++ dlls/dpnet/tests/client.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 5 deletions(-) diff --git a/dlls/dpnet/client.c b/dlls/dpnet/client.c index bf2b8d2..f6f9e79 100644 --- a/dlls/dpnet/client.c +++ b/dlls/dpnet/client.c @@ -86,8 +86,11 @@ static ULONG WINAPI IDirectPlay8ClientImpl_Release(IDirectPlay8Client *iface) TRACE("(%p) ref=%u\n", This, ref); - if (!ref) { - HeapFree(GetProcessHeap(), 0, This); + if (!ref) + { + heap_free(This->username); + heap_free(This->data); + heap_free(This); } return ref; } @@ -182,9 +185,50 @@ static HRESULT WINAPI IDirectPlay8ClientImpl_SetClientInfo(IDirectPlay8Client *i const DPN_PLAYER_INFO * const pdpnPlayerInfo, void * const pvAsyncContext, DPNHANDLE * const phAsyncHandle, const DWORD dwFlags) { - IDirectPlay8ClientImpl *This = impl_from_IDirectPlay8Client(iface); - FIXME("(%p):(%p,%p,%x): Stub\n", This, pvAsyncContext, phAsyncHandle, dwFlags); - return DPN_OK; + IDirectPlay8ClientImpl *This = impl_from_IDirectPlay8Client(iface); + FIXME("(%p):(%p,%p,%x): Semi-stub.\n", This, pvAsyncContext, phAsyncHandle, dwFlags); + + if(!pdpnPlayerInfo) + return E_POINTER; + + if(phAsyncHandle) + FIXME("Async handle currently not supported.\n"); + + if (pdpnPlayerInfo->dwInfoFlags & DPNINFO_NAME) + { + heap_free(This->username); + This->username = NULL; + + if(pdpnPlayerInfo->pwszName) + { + This->username = heap_strdupW(pdpnPlayerInfo->pwszName); + if (!This->username) + return E_OUTOFMEMORY; + } + } + + if (pdpnPlayerInfo->dwInfoFlags & DPNINFO_DATA) + { + heap_free(This->data); + This->data = NULL; + This->datasize = 0; + + if(!pdpnPlayerInfo->pvData && pdpnPlayerInfo->dwDataSize) + return E_POINTER; + + if(pdpnPlayerInfo->dwDataSize && pdpnPlayerInfo->pvData) + { + This->data = heap_alloc(pdpnPlayerInfo->dwDataSize); + if (!This->data) + return E_OUTOFMEMORY; + + This->datasize = pdpnPlayerInfo->dwDataSize; + + memcpy(This->data, pdpnPlayerInfo->pvData, pdpnPlayerInfo->dwDataSize); + } + } + + return DPN_OK; } static HRESULT WINAPI IDirectPlay8ClientImpl_GetServerInfo(IDirectPlay8Client *iface, diff --git a/dlls/dpnet/dpnet_private.h b/dlls/dpnet/dpnet_private.h index 05608a6..dc6a4f1 100644 --- a/dlls/dpnet/dpnet_private.h +++ b/dlls/dpnet/dpnet_private.h @@ -56,6 +56,9 @@ struct IDirectPlay8ClientImpl PFNDPNMESSAGEHANDLER msghandler; DWORD flags; void *usercontext; + WCHAR *username; + void *data; + DWORD datasize; DPN_SP_CAPS spcaps; }; diff --git a/dlls/dpnet/tests/client.c b/dlls/dpnet/tests/client.c index 253526a..f7d6c53 100644 --- a/dlls/dpnet/tests/client.c +++ b/dlls/dpnet/tests/client.c @@ -230,6 +230,71 @@ static void test_lobbyclient(void) } } +static void test_player_info(void) +{ + HRESULT hr; + DPN_PLAYER_INFO info; + WCHAR name[] = {'w','i','n','e',0}; + WCHAR name2[] = {'w','i','n','e','2',0}; + WCHAR data[] = {'X','X','X','X',0}; + + ZeroMemory( &info, sizeof(DPN_PLAYER_INFO) ); + info.dwSize = sizeof(DPN_PLAYER_INFO); + info.dwInfoFlags = DPNINFO_NAME; + + hr = IDirectPlay8Client_SetClientInfo(client, NULL, NULL, NULL, DPNSETCLIENTINFO_SYNC); + ok(hr == E_POINTER, "got %x\n", hr); + + info.pwszName = NULL; + hr = IDirectPlay8Client_SetClientInfo(client, &info, NULL, NULL, DPNSETCLIENTINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.pwszName = name; + hr = IDirectPlay8Client_SetClientInfo(client, &info, NULL, NULL, DPNSETCLIENTINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_NAME; + info.pwszName = name2; + hr = IDirectPlay8Client_SetClientInfo(client, &info, NULL, NULL, DPNSETCLIENTINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = NULL; + info.dwDataSize = sizeof(data); + hr = IDirectPlay8Client_SetClientInfo(client, &info, NULL, NULL, DPNSETCLIENTINFO_SYNC); + ok(hr == E_POINTER, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = data; + info.dwDataSize = 0; + hr = IDirectPlay8Client_SetClientInfo(client, &info, NULL, NULL, DPNSETCLIENTINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = data; + info.dwDataSize = sizeof(data); + hr = IDirectPlay8Client_SetClientInfo(client, &info, NULL, NULL, DPNSETCLIENTINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA | DPNINFO_NAME; + info.pwszName = name; + info.pvData = data; + info.dwDataSize = sizeof(data); + hr = IDirectPlay8Client_SetClientInfo(client, &info, NULL, NULL, DPNSETCLIENTINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + /* Leave ClientInfo with only the name set. */ + info.dwInfoFlags = DPNINFO_DATA | DPNINFO_NAME; + info.pwszName = name; + info.pvData = NULL; + info.dwDataSize = 0; + hr = IDirectPlay8Client_SetClientInfo(client, &info, NULL, NULL, DPNSETCLIENTINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); +} + static void test_cleanup_dp(void) { HRESULT hr; @@ -258,6 +323,7 @@ START_TEST(client) test_enum_service_providers(); test_enum_hosts(); test_get_sp_caps(); + test_player_info(); test_lobbyclient(); test_cleanup_dp(); } -- 1.9.1 From leslie_alistair at hotmail.com Fri Oct 28 02:07:21 2016 From: leslie_alistair at hotmail.com (Alistair Leslie-Hughes) Date: Fri, 28 Oct 2016 07:07:21 +0000 Subject: [PATCH 3/4] dpnet: Semi-stub IDirectPlay8Server SetServerInfo In-Reply-To: <20161028070627.16173-1-leslie_alistair@hotmail.com> References: <20161028070627.16173-1-leslie_alistair@hotmail.com> Message-ID: Signed-off-by: Alistair Leslie-Hughes --- dlls/dpnet/server.c | 61 +++++++++++++++++++++++++++++++--- dlls/dpnet/tests/server.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 4 deletions(-) diff --git a/dlls/dpnet/server.c b/dlls/dpnet/server.c index 3e026fc..cd54ba4 100644 --- a/dlls/dpnet/server.c +++ b/dlls/dpnet/server.c @@ -43,6 +43,10 @@ typedef struct IDirectPlay8ServerImpl PFNDPNMESSAGEHANDLER msghandler; DWORD flags; void *usercontext; + + WCHAR *servername; + void *data; + DWORD datasize; } IDirectPlay8ServerImpl; WINE_DEFAULT_DEBUG_CHANNEL(dpnet); @@ -91,8 +95,11 @@ static ULONG WINAPI IDirectPlay8ServerImpl_Release(IDirectPlay8Server *iface) TRACE("(%p) ref=%d\n", This, ref); - if (!ref) { - HeapFree(GetProcessHeap(), 0, This); + if (!ref) + { + heap_free(This->servername); + heap_free(This->data); + heap_free(This); } return ref; @@ -151,8 +158,54 @@ static HRESULT WINAPI IDirectPlay8ServerImpl_SetServerInfo(IDirectPlay8Server *i PVOID pvAsyncContext, DPNHANDLE *phAsyncHandle, DWORD dwFlags) { IDirectPlay8ServerImpl *This = impl_from_IDirectPlay8Server(iface); - FIXME("(%p)->(%p %p %p %d)\n", This, pdpnPlayerInfo, pvAsyncContext, phAsyncHandle, dwFlags); - return E_NOTIMPL; + + FIXME("(%p)->(%p %p %p %x) Semi-stub\n", This, pdpnPlayerInfo, pvAsyncContext, phAsyncHandle, dwFlags); + + if(!pdpnPlayerInfo) + return E_POINTER; + + if(!This->msghandler) + return DPNERR_UNINITIALIZED; + + if(phAsyncHandle) + FIXME("Async handle currently not supported.\n"); + + if (pdpnPlayerInfo->dwInfoFlags & DPNINFO_NAME) + { + heap_free(This->servername); + This->servername = NULL; + + if(pdpnPlayerInfo->pwszName) + { + This->servername = heap_strdupW(pdpnPlayerInfo->pwszName); + if (!This->servername) + return E_OUTOFMEMORY; + } + } + + if (pdpnPlayerInfo->dwInfoFlags & DPNINFO_DATA) + { + heap_free(This->data); + This->data = NULL; + This->datasize = 0; + + if(!pdpnPlayerInfo->pvData && pdpnPlayerInfo->dwDataSize) + return E_POINTER; + + if(pdpnPlayerInfo->dwDataSize && pdpnPlayerInfo->pvData) + { + This->data = heap_alloc(pdpnPlayerInfo->dwDataSize); + if (!This->data) + return E_OUTOFMEMORY; + + This->datasize = pdpnPlayerInfo->dwDataSize; + + memcpy(This->data, pdpnPlayerInfo->pvData, pdpnPlayerInfo->dwDataSize); + } + } + + /* TODO: Send DPN_MSGID_SERVER_INFO message to all players. */ + return S_OK; } static HRESULT WINAPI IDirectPlay8ServerImpl_GetClientInfo(IDirectPlay8Server *iface, DPNID dpnid, DPN_PLAYER_INFO *pdpnPlayerInfo, diff --git a/dlls/dpnet/tests/server.c b/dlls/dpnet/tests/server.c index 8279666..928c6a0 100644 --- a/dlls/dpnet/tests/server.c +++ b/dlls/dpnet/tests/server.c @@ -98,6 +98,88 @@ static void create_server(void) } } +static void test_server_info(void) +{ + HRESULT hr; + DPN_PLAYER_INFO info; + WCHAR name[] = {'w','i','n','e',0}; + WCHAR name2[] = {'w','i','n','e','2',0}; + WCHAR data[] = {'X','X','X','X',0}; + IDirectPlay8Server *server = NULL; + + hr = CoCreateInstance( &CLSID_DirectPlay8Server, NULL, CLSCTX_ALL, &IID_IDirectPlay8Server, (LPVOID*)&server); + ok(hr == S_OK, "Failed to create IDirectPlay8Server object\n"); + if( SUCCEEDED(hr) ) + { + ZeroMemory( &info, sizeof(DPN_PLAYER_INFO) ); + info.dwSize = sizeof(DPN_PLAYER_INFO); + info.dwInfoFlags = DPNINFO_NAME; + + hr = IDirectPlay8Server_SetServerInfo(server, NULL, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == E_POINTER, "got %x\n", hr); + + info.pwszName = name; + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == DPNERR_UNINITIALIZED, "got %x\n", hr); + + hr = IDirectPlay8Server_Initialize(server, NULL, DirectPlayMessageHandler, 0); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDirectPlay8Server_SetServerInfo(server, NULL, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == E_POINTER, "got %x\n", hr); + + info.pwszName = NULL; + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.pwszName = name; + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_NAME; + info.pwszName = name2; + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = NULL; + info.dwDataSize = sizeof(data); + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == E_POINTER, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = data; + info.dwDataSize = 0; + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = data; + info.dwDataSize = sizeof(data); + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA | DPNINFO_NAME; + info.pwszName = name; + info.pvData = data; + info.dwDataSize = sizeof(data); + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA | DPNINFO_NAME; + info.pwszName = name; + info.pvData = NULL; + info.dwDataSize = 0; + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + IDirectPlay8Server_Release(server); + } +} + START_TEST(server) { HRESULT hr; @@ -108,6 +190,7 @@ START_TEST(server) return; create_server(); + test_server_info(); CoUninitialize(); } -- 1.9.1 From leslie_alistair at hotmail.com Fri Oct 28 02:07:32 2016 From: leslie_alistair at hotmail.com (Alistair Leslie-Hughes) Date: Fri, 28 Oct 2016 07:07:32 +0000 Subject: [PATCH 4/4] dpnet: Implement IDirectPlay8LobbyClient Initialize (resend) In-Reply-To: <20161028070627.16173-1-leslie_alistair@hotmail.com> References: <20161028070627.16173-1-leslie_alistair@hotmail.com> Message-ID: Signed-off-by: Alistair Leslie-Hughes --- dlls/dpnet/client.c | 15 +++++++++++++-- dlls/dpnet/tests/client.c | 5 ++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/dlls/dpnet/client.c b/dlls/dpnet/client.c index f6f9e79..36df50d 100644 --- a/dlls/dpnet/client.c +++ b/dlls/dpnet/client.c @@ -40,6 +40,10 @@ typedef struct IDirectPlay8LobbyClientImpl { IDirectPlay8LobbyClient IDirectPlay8LobbyClient_iface; LONG ref; + + PFNDPNMESSAGEHANDLER msghandler; + DWORD flags; + void *usercontext; } IDirectPlay8LobbyClientImpl; static inline IDirectPlay8LobbyClientImpl *impl_from_IDirectPlay8LobbyClient(IDirectPlay8LobbyClient *iface) @@ -427,9 +431,16 @@ static HRESULT WINAPI lobbyclient_Initialize(IDirectPlay8LobbyClient *iface, voi { IDirectPlay8LobbyClientImpl *This = impl_from_IDirectPlay8LobbyClient(iface); - FIXME("(%p)->(%p %p 0x%08x)\n", This, context, msghandler, flags); + TRACE("(%p):(%p,%p,%x)\n", This, context, msghandler, flags); - return E_NOTIMPL; + if(!msghandler) + return E_POINTER; + + This->usercontext = context; + This->msghandler = msghandler; + This->flags = flags; + + return DPN_OK; } static HRESULT WINAPI lobbyclient_EnumLocalPrograms(IDirectPlay8LobbyClient *iface, GUID* guidapplication, diff --git a/dlls/dpnet/tests/client.c b/dlls/dpnet/tests/client.c index f7d6c53..6732034 100644 --- a/dlls/dpnet/tests/client.c +++ b/dlls/dpnet/tests/client.c @@ -220,8 +220,11 @@ static void test_lobbyclient(void) ok(hr == S_OK, "Failed to create object\n"); if(SUCCEEDED(hr)) { + hr = IDirectPlay8LobbyClient_Initialize(client, NULL, NULL, 0); + ok(hr == E_POINTER, "got 0x%08x\n", hr); + hr = IDirectPlay8LobbyClient_Initialize(client, NULL, DirectPlayLobbyClientMessageHandler, 0); - todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08x\n", hr); hr = IDirectPlay8LobbyClient_Close(client, 0); todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); -- 1.9.1 From jkucia at codeweavers.com Fri Oct 28 05:20:41 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Fri, 28 Oct 2016 12:20:41 +0200 Subject: [PATCH] wined3d: Invalidate INDEXBUFFER device state when contents of bound index buffer is changed. Message-ID: <1477650041-24160-1-git-send-email-jkucia@codeweavers.com> Fixes a regression introduced by commit e3a8cd20ced9f33db64a35f60bc8487ae8173e47. Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index a81cd64..f111ef1 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -1022,6 +1022,12 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context * } } + if (buffer->resource.bind_count) + { + if (buffer->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER) + device_invalidate_state(buffer->resource.device, STATE_INDEXBUFFER); + } + if (!buffer->conversion_map) { /* That means that there is nothing to fixup. Just upload from -- 2.7.3 From nsivov at codeweavers.com Fri Oct 28 05:23:01 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Fri, 28 Oct 2016 13:23:01 +0300 Subject: [PATCH] po: Update Russian translation Message-ID: <20161028102301.23591-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- po/ru.po | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/po/ru.po b/po/ru.po index a834c13..c071cf2 100644 --- a/po/ru.po +++ b/po/ru.po @@ -5,14 +5,14 @@ msgstr "" "Project-Id-Version: Wine\n" "Report-Msgid-Bugs-To: http://bugs.winehq.org\n" "POT-Creation-Date: N/A\n" -"PO-Revision-Date: 2016-10-14 22:09+0300\n" +"PO-Revision-Date: 2016-10-28 10:09+0300\n" "Last-Translator: Nikolay Sivov \n" "Language-Team: Russian\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.9\n" +"X-Generator: Poedit 1.8.10\n" #: appwiz.rc:58 msgid "Install/Uninstall" @@ -10513,10 +10513,8 @@ msgid "IPv6 address" msgstr "IPv6-адрес" #: msinfo32.rc:28 -#, fuzzy -#| msgid "System Configuration" msgid "System Information" -msgstr "Конфигурация системы" +msgstr "Информация о системе" #: net.rc:30 msgid "" @@ -14506,10 +14504,8 @@ msgid "Error: Invalid query\n" msgstr "Ошибка: некорректный запрос\n" #: wmic.rc:31 -#, fuzzy -#| msgid "reg: Invalid syntax. " msgid "Error: Invalid syntax for PATH\n" -msgstr "reg: неверный синтаксис. " +msgstr "Ошибка: неверный синтаксис PATH\n" #: wordpad.rc:31 msgid "&New...\tCtrl+N" -- 2.9.3 From nsivov at codeweavers.com Fri Oct 28 05:43:19 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Fri, 28 Oct 2016 13:43:19 +0300 Subject: [v2 PATCH] ucrtbase: Added _sopen_dispatch/_wsopen_dispatch Message-ID: <20161028104319.24511-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- v2: forward _wsopen/_wsopen_s and _sopen/_sopen_s to respective *_dispatch variants .../api-ms-win-crt-stdio-l1-1-0.spec | 4 +-- dlls/msvcrt/file.c | 36 ++++++++++++++++------ dlls/ucrtbase/ucrtbase.spec | 4 +-- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec b/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec index 4b8be01..6acd08e 100644 --- a/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec +++ b/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec @@ -87,7 +87,7 @@ @ cdecl _setmaxstdio(long) ucrtbase._setmaxstdio @ cdecl _setmode(long long) ucrtbase._setmode @ varargs _sopen(str long long) ucrtbase._sopen -@ stub _sopen_dispatch +@ cdecl _sopen_dispatch(str long long long ptr long) ucrtbase._sopen_dispatch @ cdecl _sopen_s(ptr str long long long) ucrtbase._sopen_s @ cdecl _tell(long) ucrtbase._tell @ cdecl -ret64 _telli64(long) ucrtbase._telli64 @@ -107,7 +107,7 @@ @ cdecl _wpopen(wstr wstr) ucrtbase._wpopen @ cdecl _write(long ptr long) ucrtbase._write @ varargs _wsopen(wstr long long) ucrtbase._wsopen -@ stub _wsopen_dispatch +@ cdecl _wsopen_dispatch(wstr long long long ptr long) ucrtbase._wsopen_dispatch @ cdecl _wsopen_s(ptr wstr long long long) ucrtbase._wsopen_s @ cdecl _wtempnam(wstr wstr) ucrtbase._wtempnam @ cdecl _wtmpnam(ptr) ucrtbase._wtmpnam diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index 432d5c7..37e5ece 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -2144,9 +2144,10 @@ static int check_bom(HANDLE h, int oflags, BOOL seek) } /********************************************************************* - * _wsopen_s (MSVCRT.@) + * _wsopen_dispatch (UCRTBASE.@) */ -int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int shflags, int pmode ) +int CDECL MSVCRT__wsopen_dispatch( const MSVCRT_wchar_t* path, int oflags, int shflags, int pmode, + int *fd, int secure ) { DWORD access = 0, creation = 0, attrib; SECURITY_ATTRIBUTES sa; @@ -2306,6 +2307,15 @@ int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int return 0; } + +/********************************************************************* + * _wsopen_s (MSVCRT.@) + */ +int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int shflags, int pmode ) +{ + return MSVCRT__wsopen_dispatch( path, oflags, shflags, pmode, fd, 1 ); +} + /********************************************************************* * _wsopen (MSVCRT.@) */ @@ -2325,14 +2335,15 @@ int CDECL MSVCRT__wsopen( const MSVCRT_wchar_t *path, int oflags, int shflags, . else pmode = 0; - MSVCRT__wsopen_s(&fd, path, oflags, shflags, pmode); - return fd; + return MSVCRT__wsopen_dispatch(path, oflags, shflags, pmode, &fd, 0) ? -1 : fd; } + /********************************************************************* - * _sopen_s (MSVCRT.@) + * _sopen_dispatch (UCRTBASE.@) */ -int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, int pmode ) +int CDECL MSVCRT__sopen_dispatch( const char *path, int oflags, int shflags, + int pmode, int *fd, int secure) { MSVCRT_wchar_t *pathW; int ret; @@ -2343,12 +2354,20 @@ int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, i if(!MSVCRT_CHECK_PMT(path && (pathW = msvcrt_wstrdupa(path)))) return MSVCRT_EINVAL; - ret = MSVCRT__wsopen_s(fd, pathW, oflags, shflags, pmode); + ret = MSVCRT__wsopen_dispatch(pathW, oflags, shflags, pmode, fd, secure); MSVCRT_free(pathW); return ret; } /********************************************************************* + * _sopen_s (MSVCRT.@) + */ +int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, int pmode ) +{ + return MSVCRT__sopen_dispatch(path, oflags, shflags, pmode, fd, 1); +} + +/********************************************************************* * _sopen (MSVCRT.@) */ int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... ) @@ -2367,8 +2386,7 @@ int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... ) else pmode = 0; - MSVCRT__sopen_s(&fd, path, oflags, shflags, pmode); - return fd; + return MSVCRT__sopen_dispatch(path, oflags, shflags, pmode, &fd, 0) ? -1 : fd; } /********************************************************************* diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index f0598ce..47608f9 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -1902,7 +1902,7 @@ @ stub _setsystime(ptr long) @ cdecl _sleep(long) MSVCRT__sleep @ varargs _sopen(str long long) MSVCRT__sopen -@ stub _sopen_dispatch +@ cdecl _sopen_dispatch(str long long long ptr long) MSVCRT__sopen_dispatch @ cdecl _sopen_s(ptr str long long long) MSVCRT__sopen_s @ varargs _spawnl(long str str) @ varargs _spawnle(long str str) @@ -2109,7 +2109,7 @@ @ cdecl _wsearchenv_s(wstr wstr ptr long) MSVCRT__wsearchenv_s @ cdecl _wsetlocale(long wstr) MSVCRT__wsetlocale @ varargs _wsopen(wstr long long) MSVCRT__wsopen -@ stub _wsopen_dispatch +@ cdecl _wsopen_dispatch(wstr long long long ptr long) MSVCRT__wsopen_dispatch @ cdecl _wsopen_s(ptr wstr long long long) MSVCRT__wsopen_s @ varargs _wspawnl(long wstr wstr) @ varargs _wspawnle(long wstr wstr) -- 2.9.3 From nsivov at codeweavers.com Fri Oct 28 06:23:46 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Fri, 28 Oct 2016 14:23:46 +0300 Subject: [PATCH] d2d1: Use transformed geometry to translate glyph run outline Message-ID: <20161028112346.25685-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/d2d1/render_target.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index 798dd0d..b143958 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -873,8 +873,9 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawTextLayout(ID2D1RenderTa static void d2d_rt_draw_glyph_run_outline(struct d2d_d3d_render_target *render_target, D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush) { - D2D1_MATRIX_3X2_F *transform, prev_transform; + ID2D1TransformedGeometry *transformed_geometry; ID2D1PathGeometry *geometry; + D2D1_MATRIX_3X2_F transform; ID2D1GeometrySink *sink; HRESULT hr; @@ -905,15 +906,25 @@ static void d2d_rt_draw_glyph_run_outline(struct d2d_d3d_render_target *render_t ERR("Failed to close geometry sink, hr %#x.\n", hr); ID2D1GeometrySink_Release(sink); - transform = &render_target->drawing_state.transform; - prev_transform = *transform; - transform->_31 += baseline_origin.x * transform->_11 + baseline_origin.y * transform->_21; - transform->_32 += baseline_origin.x * transform->_12 + baseline_origin.y * transform->_22; - d2d_rt_fill_geometry(render_target, unsafe_impl_from_ID2D1Geometry((ID2D1Geometry *)geometry), + transform._11 = 1.0f; + transform._12 = 0.0f; + transform._21 = 0.0f; + transform._22 = 1.0f; + transform._31 = baseline_origin.x; + transform._32 = baseline_origin.y; + hr = ID2D1Factory_CreateTransformedGeometry(render_target->factory, (ID2D1Geometry *)geometry, + &transform, &transformed_geometry); + ID2D1PathGeometry_Release(geometry); + if (FAILED(hr)) + { + ERR("Failed to create transformed glyph run geometry, hr %#x.\n", hr); + return; + } + + d2d_rt_fill_geometry(render_target, unsafe_impl_from_ID2D1Geometry((ID2D1Geometry *)transformed_geometry), unsafe_impl_from_ID2D1Brush(brush), NULL); - *transform = prev_transform; - ID2D1PathGeometry_Release(geometry); + ID2D1TransformedGeometry_Release(transformed_geometry); } static void d2d_rt_draw_glyph_run_bitmap(struct d2d_d3d_render_target *render_target, -- 2.9.3 From nsivov at codeweavers.com Fri Oct 28 06:52:49 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Fri, 28 Oct 2016 14:52:49 +0300 Subject: [v3 PATCH] ucrtbase: Added _sopen_dispatch/_wsopen_dispatch Message-ID: <20161028115249.26131-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- v3: fixed trace message v2: fixed forwarding direction .../api-ms-win-crt-stdio-l1-1-0.spec | 4 +-- dlls/msvcrt/file.c | 40 ++++++++++++++++------ dlls/ucrtbase/ucrtbase.spec | 4 +-- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec b/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec index 4b8be01..6acd08e 100644 --- a/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec +++ b/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec @@ -87,7 +87,7 @@ @ cdecl _setmaxstdio(long) ucrtbase._setmaxstdio @ cdecl _setmode(long long) ucrtbase._setmode @ varargs _sopen(str long long) ucrtbase._sopen -@ stub _sopen_dispatch +@ cdecl _sopen_dispatch(str long long long ptr long) ucrtbase._sopen_dispatch @ cdecl _sopen_s(ptr str long long long) ucrtbase._sopen_s @ cdecl _tell(long) ucrtbase._tell @ cdecl -ret64 _telli64(long) ucrtbase._telli64 @@ -107,7 +107,7 @@ @ cdecl _wpopen(wstr wstr) ucrtbase._wpopen @ cdecl _write(long ptr long) ucrtbase._write @ varargs _wsopen(wstr long long) ucrtbase._wsopen -@ stub _wsopen_dispatch +@ cdecl _wsopen_dispatch(wstr long long long ptr long) ucrtbase._wsopen_dispatch @ cdecl _wsopen_s(ptr wstr long long long) ucrtbase._wsopen_s @ cdecl _wtempnam(wstr wstr) ucrtbase._wtempnam @ cdecl _wtmpnam(ptr) ucrtbase._wtmpnam diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index 432d5c7..8965156 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -2144,9 +2144,10 @@ static int check_bom(HANDLE h, int oflags, BOOL seek) } /********************************************************************* - * _wsopen_s (MSVCRT.@) + * _wsopen_dispatch (UCRTBASE.@) */ -int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int shflags, int pmode ) +int CDECL MSVCRT__wsopen_dispatch( const MSVCRT_wchar_t* path, int oflags, int shflags, int pmode, + int *fd, int secure ) { DWORD access = 0, creation = 0, attrib; SECURITY_ATTRIBUTES sa; @@ -2154,8 +2155,8 @@ int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int int wxflag; HANDLE hand; - TRACE("fd*: %p :file (%s) oflags: 0x%04x shflags: 0x%04x pmode: 0x%04x\n", - fd, debugstr_w(path), oflags, shflags, pmode); + TRACE("path: (%s) oflags: 0x%04x shflags: 0x%04x pmode: 0x%04x fd*: %p secure: %d\n", + debugstr_w(path), oflags, shflags, pmode, fd, secure); if (!MSVCRT_CHECK_PMT( fd != NULL )) return MSVCRT_EINVAL; @@ -2306,6 +2307,15 @@ int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int return 0; } + +/********************************************************************* + * _wsopen_s (MSVCRT.@) + */ +int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int shflags, int pmode ) +{ + return MSVCRT__wsopen_dispatch( path, oflags, shflags, pmode, fd, 1 ); +} + /********************************************************************* * _wsopen (MSVCRT.@) */ @@ -2325,14 +2335,15 @@ int CDECL MSVCRT__wsopen( const MSVCRT_wchar_t *path, int oflags, int shflags, . else pmode = 0; - MSVCRT__wsopen_s(&fd, path, oflags, shflags, pmode); - return fd; + return MSVCRT__wsopen_dispatch(path, oflags, shflags, pmode, &fd, 0) ? -1 : fd; } + /********************************************************************* - * _sopen_s (MSVCRT.@) + * _sopen_dispatch (UCRTBASE.@) */ -int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, int pmode ) +int CDECL MSVCRT__sopen_dispatch( const char *path, int oflags, int shflags, + int pmode, int *fd, int secure) { MSVCRT_wchar_t *pathW; int ret; @@ -2343,12 +2354,20 @@ int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, i if(!MSVCRT_CHECK_PMT(path && (pathW = msvcrt_wstrdupa(path)))) return MSVCRT_EINVAL; - ret = MSVCRT__wsopen_s(fd, pathW, oflags, shflags, pmode); + ret = MSVCRT__wsopen_dispatch(pathW, oflags, shflags, pmode, fd, secure); MSVCRT_free(pathW); return ret; } /********************************************************************* + * _sopen_s (MSVCRT.@) + */ +int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, int pmode ) +{ + return MSVCRT__sopen_dispatch(path, oflags, shflags, pmode, fd, 1); +} + +/********************************************************************* * _sopen (MSVCRT.@) */ int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... ) @@ -2367,8 +2386,7 @@ int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... ) else pmode = 0; - MSVCRT__sopen_s(&fd, path, oflags, shflags, pmode); - return fd; + return MSVCRT__sopen_dispatch(path, oflags, shflags, pmode, &fd, 0) ? -1 : fd; } /********************************************************************* diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index f0598ce..47608f9 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -1902,7 +1902,7 @@ @ stub _setsystime(ptr long) @ cdecl _sleep(long) MSVCRT__sleep @ varargs _sopen(str long long) MSVCRT__sopen -@ stub _sopen_dispatch +@ cdecl _sopen_dispatch(str long long long ptr long) MSVCRT__sopen_dispatch @ cdecl _sopen_s(ptr str long long long) MSVCRT__sopen_s @ varargs _spawnl(long str str) @ varargs _spawnle(long str str) @@ -2109,7 +2109,7 @@ @ cdecl _wsearchenv_s(wstr wstr ptr long) MSVCRT__wsearchenv_s @ cdecl _wsetlocale(long wstr) MSVCRT__wsetlocale @ varargs _wsopen(wstr long long) MSVCRT__wsopen -@ stub _wsopen_dispatch +@ cdecl _wsopen_dispatch(wstr long long long ptr long) MSVCRT__wsopen_dispatch @ cdecl _wsopen_s(ptr wstr long long long) MSVCRT__wsopen_s @ varargs _wspawnl(long wstr wstr) @ varargs _wspawnle(long wstr wstr) -- 2.9.3 From hverbeet at codeweavers.com Fri Oct 28 08:55:08 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 28 Oct 2016 15:55:08 +0200 Subject: [PATCH 1/2] d2d1: Support setting and getting back start and end point for linear gradient brush In-Reply-To: <20161028065106.11936-1-nsivov@codeweavers.com> References: <20161028065106.11936-1-nsivov@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Fri Oct 28 08:55:09 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Fri, 28 Oct 2016 15:55:09 +0200 Subject: [PATCH 2/2] d2d1: Store gradient stop collection pointer for linear gradient brush In-Reply-To: <20161028065106.11936-2-nsivov@codeweavers.com> References: <20161028065106.11936-2-nsivov@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From donat at enikeev.net Fri Oct 28 10:15:37 2016 From: donat at enikeev.net (Donat Enikeev) Date: Fri, 28 Oct 2016 18:15:37 +0300 Subject: [PATCH 1/2] crypt32/tests: testing priorities and flags of stores in a collection; and whether certs are saved in registry endpoint In-Reply-To: References: Message-ID: <1477667737-12008-1-git-send-email-donat@enikeev.net> Superceeds: https://source.winehq.org/patches/data/127162 v1: Test of priorities and flags of stores in a collection v2: Test whether certificates are actually saved in the registry for the most common pathes and one todo for HLCU\My saved in the AppData Signed-off-by: Donat Enikeev --- dlls/crypt32/tests/Makefile.in | 2 +- dlls/crypt32/tests/store.c | 288 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 289 insertions(+), 1 deletion(-) diff --git a/dlls/crypt32/tests/Makefile.in b/dlls/crypt32/tests/Makefile.in index d84ca17..d96ad1c 100644 --- a/dlls/crypt32/tests/Makefile.in +++ b/dlls/crypt32/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = crypt32.dll -IMPORTS = crypt32 advapi32 +IMPORTS = crypt32 advapi32 user32 shlwapi shell32 C_SRCS = \ base64.c \ diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c index e811fbe..7fedaa4 100644 --- a/dlls/crypt32/tests/store.c +++ b/dlls/crypt32/tests/store.c @@ -23,6 +23,9 @@ #include #include +#include +#include +#include #include #include #include @@ -347,6 +350,287 @@ static const BYTE serializedStoreWithCert[] = { 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00 }; +static const struct +{ + HKEY key; + DWORD cert_store; + BOOL todo_appdata_file; + WCHAR store_name[MAX_PATH]; + LPCWSTR base_reg_path; +} reg_store_saved_certs[] = { + { HKEY_LOCAL_MACHINE, CERT_SYSTEM_STORE_LOCAL_MACHINE, FALSE, + {'R','O','O','T',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH }, + { HKEY_LOCAL_MACHINE, CERT_SYSTEM_STORE_LOCAL_MACHINE, FALSE, + {'M','Y',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH }, + { HKEY_LOCAL_MACHINE, CERT_SYSTEM_STORE_LOCAL_MACHINE, FALSE, + {'C','A',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH }, + /* Adding to HKCU\Root triggers safety warning dialog at least on Win764 */ + /* { HKEY_CURRENT_USER, CERT_SYSTEM_STORE_CURRENT_USER, + {'R','O','O','T',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH }, */ + { HKEY_CURRENT_USER, CERT_SYSTEM_STORE_CURRENT_USER, TRUE, + {'M','Y',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH }, + { HKEY_CURRENT_USER, CERT_SYSTEM_STORE_CURRENT_USER, FALSE, + {'C','A',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH } +}; + +/* Testing whether system stores are available for adding new certs + * and checking directly in the registry whether they are actually saved or deleted. + * However, by the moment Windows treats HKCU\My (at least) as a special case, + * and uses AppData directory for storing certs, not registry + * @see additionally testRegStore() verifying a content of read/saved certs + */ +static void testRegStoreSavedCerts(void) +{ + static const WCHAR fmt[] = + { '%','s','\\','%','s','\\','%','s','\\','%','s',0}, + ms_certs[] = + { 'M','i','c','r','o','s','o','f','t','\\','S','y','s','t','e','m','C','e','r','t','i','f','i','c','a','t','e','s',0}, + certs[] = + {'C','e','r','t','i','f','i','c','a','t','e','s',0}, + bigCert_hash[] = { + '6','E','3','0','9','0','7','1','5','F','D','9','2','3', + '5','6','E','B','A','E','2','5','4','0','E','6','2','2', + 'D','A','1','9','2','6','0','2','A','6','0','8',0}; + PCCERT_CONTEXT cert1, cert2; + HCERTSTORE store; + HANDLE cert_file; + HRESULT pathres; + WCHAR key_name[MAX_PATH], appdata_path[MAX_PATH]; + HKEY key; + BOOL ret; + DWORD res,i; + + for (i = 0; i < sizeof(reg_store_saved_certs) / sizeof(reg_store_saved_certs[0]); i++) + { + store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + reg_store_saved_certs[i].cert_store, reg_store_saved_certs[i].store_name); + if (!store) + { + win_skip("Insufficient privileges for the test %d, skipping\n", i); + continue; + } + ok (store!=NULL, "Failed to open the store at %d, %x", i, GetLastError()); + cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); + ok (cert1 != NULL, "Create cert context failed at %d, %x\n", i, GetLastError()); + ret = CertAddCertificateContextToStore(store, cert1, CERT_STORE_ADD_REPLACE_EXISTING, NULL); + ok (ret, "Adding to the store failed at %d, %x\n", i, GetLastError()); + CertFreeCertificateContext(cert1); + CertCloseStore(store, 0); + + wsprintfW(key_name, fmt, reg_store_saved_certs[i].base_reg_path, + reg_store_saved_certs[i].store_name, certs, bigCert_hash); + + if (!reg_store_saved_certs[i].todo_appdata_file) + { + res = RegOpenKeyExW(reg_store_saved_certs[i].key, key_name, 0, KEY_ALL_ACCESS, &key); + ok (!res, "The cert hasn't been saved at %d, %x\n", i, GetLastError()); + if (!res) RegCloseKey(key); + } else + { + pathres = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, appdata_path); + ok (pathres == S_OK, + "Failed to get app data path at %d (%x)\n", pathres, GetLastError()); + if (pathres == S_OK) + { + PathAppendW(appdata_path, ms_certs); + PathAppendW(appdata_path, reg_store_saved_certs[i].store_name); + PathAppendW(appdata_path, certs); + PathAppendW(appdata_path, bigCert_hash); + + cert_file = CreateFileW(appdata_path, GENERIC_READ, 0, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + todo_wine + { + ok (cert_file != INVALID_HANDLE_VALUE, + "Cert was not saved in AppData at %d (%x)\n", i, GetLastError()); + } + CloseHandle(cert_file); + } + } + + /* deleting cert from store */ + store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + reg_store_saved_certs[i].cert_store, reg_store_saved_certs[i].store_name); + ok (store!=NULL, "Failed to open the store at %d, %x", i, GetLastError()); + + cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); + ok (cert1 != NULL, "Create cert context failed at %d, %x\n", i, GetLastError()); + + cert2 = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, + CERT_FIND_EXISTING, cert1, NULL); + ok (cert2 != NULL, "Failed to find cert in the store at %d, %x\n", i, GetLastError()); + + ret = CertDeleteCertificateFromStore(cert2); + ok (ret, "Failed to delete certificate from store at %d, %x\n", i, GetLastError()); + + CertFreeCertificateContext(cert1); + CertFreeCertificateContext(cert2); + CertCloseStore(store, 0); + + res = RegOpenKeyExW(reg_store_saved_certs[i].key, key_name, 0, KEY_ALL_ACCESS, &key); + ok (res, "The cert's registry entry should be absent at %i, %x\n", i, GetLastError()); + if (res) RegCloseKey(key); + + if (reg_store_saved_certs[i].todo_appdata_file) + { + cert_file = CreateFileW(appdata_path, GENERIC_READ, 0, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + ok (cert_file == INVALID_HANDLE_VALUE, + "Cert should have been absent in AppData %d\n", i); + + CloseHandle(cert_file); + } + } +} + +/** + * This test checks that certificate falls into correct store of a collection + * depending on the access flags and priorities + * @see additionally testCollectionStore() + */ +static void testStoresInCollection(void) +{ + PCCERT_CONTEXT cert1, cert2, tcert1; + HCERTSTORE collection, ro_store, rw_store, rw_store_2, tstore; + static const WCHAR WineTestRO_W[] = { 'W','i','n','e','T','e','s','t','_','R','O',0 }, + WineTestRW_W[] = { 'W','i','n','e','T','e','s','t','_','R','W',0 }, + WineTestRW2_W[]= { 'W','i','n','e','T','e','s','t','_','R','W','2',0 }; + BOOL ret; + + if (!pCertAddStoreToCollection) + { + win_skip("CertAddStoreToCollection() is not available\n"); + return; + } + collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + ok(collection != NULL, "Failed to init collection store, last error %x\n", GetLastError()); + /* Add read-only store to collection with very high priority*/ + ro_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, + CERT_SYSTEM_STORE_CURRENT_USER, WineTestRO_W); + ok(ro_store != NULL, "Failed to init ro store %x\n", GetLastError()); + + ret = CertAddStoreToCollection(collection, ro_store, 0, 1000); + ok (ret, "Failed to add read-only store to collection %x\n", GetLastError()); + + cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); + ok (cert1 != NULL, "Create cert context failed %x\n", GetLastError()); + ret = CertAddCertificateContextToStore(collection, cert1, CERT_STORE_ADD_ALWAYS, NULL); + ok (!ret, "Added cert to collection with single read-only store %x\n", GetLastError()); + + /* Add read-write store to collection with the lowest priority*/ + rw_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, + CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW_W); + ok (rw_store != NULL, "Failed to open rw store %x\n", GetLastError()); + ret = CertAddStoreToCollection(collection, rw_store, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); + ok (ret, "Failed to add rw store to collection %x\n", GetLastError()); + /** Adding certificate to collection should fall into rw store, + * even though prioirty of the ro_store is higher */ + ret = CertAddCertificateContextToStore(collection, cert1, CERT_STORE_ADD_REPLACE_EXISTING, NULL); + ok (ret, "Failed to add cert to the collection %x\n", GetLastError()); + + tcert1 = CertEnumCertificatesInStore(ro_store, NULL); + ok (!tcert1, "Read-only ro_store contains cert\n"); + + tcert1 = CertEnumCertificatesInStore(rw_store, NULL); + ok (cert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, + "Unexpected cert in the rw store\n"); + CertFreeCertificateContext(tcert1); + + tcert1 = CertEnumCertificatesInStore(collection, NULL); + ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, + "Unexpected cert in the collection\n"); + CertFreeCertificateContext(tcert1); + + /** adding one more rw store with higher priority*/ + rw_store_2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, + CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW2_W); + ok (rw_store_2 != NULL, "Failed to init second rw store %x\n", GetLastError()); + ret = CertAddStoreToCollection(collection, rw_store_2, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 50); + ok (ret, "Failed to add rw_store_2 to collection %x\n",GetLastError()); + + cert2 = CertCreateCertificateContext(X509_ASN_ENCODING, signedBigCert, sizeof(signedBigCert)); + ok (cert2 != NULL, "Failed to create cert context %x \n", GetLastError()); + ret = CertAddCertificateContextToStore(collection, cert2, CERT_STORE_ADD_REPLACE_EXISTING, NULL); + ok (ret, "Failed to add cert3 to the store %x\n",GetLastError()); + + /** checking certificates in the stores */ + tcert1 = CertEnumCertificatesInStore(ro_store, 0); + ok (tcert1 == NULL, "Read-only store not empty\n"); + + tcert1 = CertEnumCertificatesInStore(rw_store, NULL); + ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, + "Unexpected cert in the rw_store\n"); + CertFreeCertificateContext(tcert1); + + tcert1 = CertEnumCertificatesInStore(rw_store_2, NULL); + ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded, + "Unexpected cert in the rw_store_2\n"); + CertFreeCertificateContext(tcert1); + + /** checking certificates in the collection */ + tcert1 = CertEnumCertificatesInStore(collection, NULL); + ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded, + "cert2 expected in the collection got %p, %x\n",tcert1, GetLastError()); + tcert1 = CertEnumCertificatesInStore(collection, tcert1); + ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, + "cert1 expected in the collection got %p, %x\n",tcert1, GetLastError()); + tcert1 = CertEnumCertificatesInStore(collection, tcert1); + ok (tcert1==NULL,"Unexpected cert in the collection %p %x\n",tcert1, GetLastError()); + + /* checking whether certs had been saved (they are NOT in wine until stores are closed*/ + tstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, WineTestRW_W); + ok (tstore!=NULL, "Failed to open existing rw store\n"); + tcert1 = CertEnumCertificatesInStore(tstore, NULL); + todo_wine + ok(tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, "cert1 wasn't saved\n"); + CertFreeCertificateContext(tcert1); + CertCloseStore(tstore,0); + + tstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, WineTestRW2_W); + ok (tstore!=NULL, "Failed to open existing rw2 store\n"); + tcert1 = CertEnumCertificatesInStore(tstore, NULL); + todo_wine + ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded, "cert2 wasn't saved\n"); + CertFreeCertificateContext(tcert1); + CertCloseStore(tstore,0); + + /* now closing stores, certs are only then saved */ + CertCloseStore(collection,0); + CertCloseStore(ro_store,0); + CertCloseStore(rw_store,0); + CertCloseStore(rw_store_2,0); + + /* reopening registry stores to check whether certs had been saved (they should be this time)*/ + rw_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW_W); + tcert1 = CertEnumCertificatesInStore(rw_store, NULL); + ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, + "Unexpected cert in store %p\n", tcert1); + CertFreeCertificateContext(tcert1); + CertCloseStore(rw_store,0); + + rw_store_2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW2_W); + tcert1 = CertEnumCertificatesInStore(rw_store_2, NULL); + ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded, + "Unexpected cert in store %p\n", tcert1); + CertFreeCertificateContext(tcert1); + CertCloseStore(rw_store_2,0); + + CertFreeCertificateContext(cert1); + CertFreeCertificateContext(cert2); + CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRO_W); + CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRW_W); + CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0, + CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRW2_W); + +} + static void testCollectionStore(void) { HCERTSTORE store1, store2, collection, collection2; @@ -2894,7 +3178,11 @@ START_TEST(store) /* various combinations of CertOpenStore */ testMemStore(); testCollectionStore(); + testStoresInCollection(); + testRegStore(); + testRegStoreSavedCerts(); + testSystemRegStore(); testSystemStore(); testFileStore(); -- 2.7.4 From donat at enikeev.net Fri Oct 28 10:16:42 2016 From: donat at enikeev.net (Donat Enikeev) Date: Fri, 28 Oct 2016 18:16:42 +0300 Subject: [PATCH 2/2] crypt32: importing system root certs into volatile registry keys instead of dedicated RootStore In-Reply-To: References: Message-ID: <1477667802-12090-1-git-send-email-donat@enikeev.net> Fixes bug: https://bugs.winehq.org/show_bug.cgi?id=30187 Follows proposals of Jacek Caban @wine-devel Superceeds: https://source.winehq.org/patches/data/127163 v2: 1. importing system root certs into volatile registry keys using existing functions 2. RootStore removal v3: Mutex, clean-ups Signed-off-by: Donat Enikeev --- dlls/crypt32/crypt32_private.h | 6 ++- dlls/crypt32/main.c | 1 - dlls/crypt32/regstore.c | 10 ++-- dlls/crypt32/rootstore.c | 114 ++++++++++++----------------------------- dlls/crypt32/store.c | 12 ++--- 5 files changed, 47 insertions(+), 96 deletions(-) diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h index ad4a827..addff9b 100644 --- a/dlls/crypt32/crypt32_private.h +++ b/dlls/crypt32/crypt32_private.h @@ -336,7 +336,11 @@ WINECRYPT_CERTSTORE *CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara) DECLSPEC_HIDDEN; WINECRYPT_CERTSTORE *CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara) DECLSPEC_HIDDEN; -WINECRYPT_CERTSTORE *CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags) DECLSPEC_HIDDEN; + +void CRYPT_ImportSystemRootCertsToReg(void) DECLSPEC_HIDDEN; +BOOL CRYPT_SerializeContextsToReg(HKEY key, DWORD dwFlags, const WINE_CONTEXT_INTERFACE *contextInterface, + HCERTSTORE memStore) DECLSPEC_HIDDEN; + BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert) DECLSPEC_HIDDEN; /* Allocates and initializes a certificate chain engine, but without creating diff --git a/dlls/crypt32/main.c b/dlls/crypt32/main.c index 241a1d9..9ff7592 100644 --- a/dlls/crypt32/main.c +++ b/dlls/crypt32/main.c @@ -49,7 +49,6 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved) if (pvReserved) break; crypt_oid_free(); crypt_sip_free(); - root_store_free(); default_chain_engine_free(); if (hDefProv) CryptReleaseContext(hDefProv, 0); break; diff --git a/dlls/crypt32/regstore.c b/dlls/crypt32/regstore.c index b79387f..750f315 100644 --- a/dlls/crypt32/regstore.c +++ b/dlls/crypt32/regstore.c @@ -179,7 +179,7 @@ static void CRYPT_RegReadFromReg(HKEY key, HCERTSTORE store) } /* Hash is assumed to be 20 bytes in length (a SHA-1 hash) */ -static BOOL CRYPT_WriteSerializedToReg(HKEY key, const BYTE *hash, const BYTE *buf, +static BOOL CRYPT_WriteSerializedToReg(HKEY key, DWORD dwFlags, const BYTE *hash, const BYTE *buf, DWORD len) { WCHAR asciiHash[20 * 2 + 1]; @@ -188,7 +188,7 @@ static BOOL CRYPT_WriteSerializedToReg(HKEY key, const BYTE *hash, const BYTE *b BOOL ret; CRYPT_HashToStr(hash, asciiHash); - rc = RegCreateKeyExW(key, asciiHash, 0, NULL, 0, KEY_ALL_ACCESS, NULL, + rc = RegCreateKeyExW(key, asciiHash, 0, NULL, dwFlags, KEY_ALL_ACCESS, NULL, &subKey, NULL); if (!rc) { @@ -205,7 +205,7 @@ static BOOL CRYPT_WriteSerializedToReg(HKEY key, const BYTE *hash, const BYTE *b return ret; } -static BOOL CRYPT_SerializeContextsToReg(HKEY key, +BOOL CRYPT_SerializeContextsToReg(HKEY key, DWORD dwFlags, const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE memStore) { const void *context = NULL; @@ -232,7 +232,7 @@ static BOOL CRYPT_SerializeContextsToReg(HKEY key, { ret = contextInterface->serialize(context, 0, buf, &size); if (ret) - ret = CRYPT_WriteSerializedToReg(key, hash, buf, size); + ret = CRYPT_WriteSerializedToReg(key, dwFlags, hash, buf, size); } CryptMemFree(buf); } @@ -287,7 +287,7 @@ static BOOL CRYPT_RegWriteToReg(WINE_REGSTOREINFO *store) } LeaveCriticalSection(&store->cs); } - ret = CRYPT_SerializeContextsToReg(key, interfaces[i], + ret = CRYPT_SerializeContextsToReg(key, 0, interfaces[i], store->memStore); RegCloseKey(key); } diff --git a/dlls/crypt32/rootstore.c b/dlls/crypt32/rootstore.c index 5cee235..5bf77db 100644 --- a/dlls/crypt32/rootstore.c +++ b/dlls/crypt32/rootstore.c @@ -435,53 +435,6 @@ static BOOL import_certs_from_path(LPCSTR path, HCERTSTORE store, return ret; } -static BOOL WINAPI CRYPT_RootWriteCert(HCERTSTORE hCertStore, - PCCERT_CONTEXT cert, DWORD dwFlags) -{ - /* The root store can't have certs added */ - return FALSE; -} - -static BOOL WINAPI CRYPT_RootDeleteCert(HCERTSTORE hCertStore, - PCCERT_CONTEXT cert, DWORD dwFlags) -{ - /* The root store can't have certs deleted */ - return FALSE; -} - -static BOOL WINAPI CRYPT_RootWriteCRL(HCERTSTORE hCertStore, - PCCRL_CONTEXT crl, DWORD dwFlags) -{ - /* The root store can have CRLs added. At worst, a malicious application - * can DoS itself, as the changes aren't persisted in any way. - */ - return TRUE; -} - -static BOOL WINAPI CRYPT_RootDeleteCRL(HCERTSTORE hCertStore, - PCCRL_CONTEXT crl, DWORD dwFlags) -{ - /* The root store can't have CRLs deleted */ - return FALSE; -} - -static void *rootProvFuncs[] = { - NULL, /* CERT_STORE_PROV_CLOSE_FUNC */ - NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */ - CRYPT_RootWriteCert, - CRYPT_RootDeleteCert, - NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */ - NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */ - CRYPT_RootWriteCRL, - CRYPT_RootDeleteCRL, - NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */ - NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */ - NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */ - NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */ - NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */ - NULL, /* CERT_STORE_PROV_CONTROL_FUNC */ -}; - static const char * const CRYPT_knownLocations[] = { "/etc/ssl/certs/ca-certificates.crt", "/etc/ssl/certs", @@ -790,55 +743,56 @@ static void read_trusted_roots_from_known_locations(HCERTSTORE store) static HCERTSTORE create_root_store(void) { - HCERTSTORE root = NULL; HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); if (memStore) { - CERT_STORE_PROV_INFO provInfo = { - sizeof(CERT_STORE_PROV_INFO), - sizeof(rootProvFuncs) / sizeof(rootProvFuncs[0]), - rootProvFuncs, - NULL, - 0, - NULL - }; - read_trusted_roots_from_known_locations(memStore); add_ms_root_certs(memStore); - root = CRYPT_ProvCreateStore(0, memStore, &provInfo); } - TRACE("returning %p\n", root); - return root; + + TRACE("returning %p\n", memStore); + return memStore; } -static WINECRYPT_CERTSTORE *CRYPT_rootStore; +static const WCHAR certs_root_pathW[] = + {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', + 'S','y','s','t','e','m','C','e','r','t','i','f','i','c','a','t','e','s','\\', + 'R','o','o','t','\\', 'C','e','r','t','i','f','i','c','a','t','e','s', 0}; +static const WCHAR mutex_nameW[] = + {'_','_','W','I','N','E','_','C','R','Y','P','T','_','M','U','T','E','X','_','_','\0'}; + -WINECRYPT_CERTSTORE *CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags) +void CRYPT_ImportSystemRootCertsToReg(void) { - TRACE("(%ld, %08x)\n", hCryptProv, dwFlags); + HCERTSTORE store = NULL; + HKEY key; + LONG rc; + HANDLE mutex; - if (dwFlags & CERT_STORE_DELETE_FLAG) + TRACE("\n"); + + mutex = CreateMutexW( NULL, FALSE, mutex_nameW); + if (!mutex) { - WARN("root store can't be deleted\n"); - SetLastError(ERROR_ACCESS_DENIED); - return NULL; + ERR("Failed to create mutex, %08x\n", GetLastError()); + return; } - if (!CRYPT_rootStore) + if ( GetLastError() == ERROR_ALREADY_EXISTS ) + return; + + if (!(store = create_root_store())) + return; + + rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, certs_root_pathW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, 0); + if (!rc) { - HCERTSTORE root = create_root_store(); + if (!CRYPT_SerializeContextsToReg(key, REG_OPTION_VOLATILE, pCertInterface, store)) + WARN("Failed to import system certs into registry, %08x\n", GetLastError()); - InterlockedCompareExchangePointer((PVOID *)&CRYPT_rootStore, root, - NULL); - if (CRYPT_rootStore != root) - CertCloseStore(root, 0); + RegCloseKey(key); } - CRYPT_rootStore->vtbl->addref(CRYPT_rootStore); - return CRYPT_rootStore; -} -void root_store_free(void) -{ - CertCloseStore(CRYPT_rootStore, 0); -} + CertCloseStore(store, 0); +} \ No newline at end of file diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c index 356712b..19eca22 100644 --- a/dlls/crypt32/store.c +++ b/dlls/crypt32/store.c @@ -424,21 +424,15 @@ static WINECRYPT_CERTSTORE *CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv, SetLastError(E_INVALIDARG); return NULL; } - /* FIXME: In Windows, the root store (even the current user location) is - * protected: adding to it or removing from it present a user interface, - * and the keys are owned by the system process, not the current user. - * Wine's registry doesn't implement access controls, so a similar - * mechanism isn't possible yet. - */ - if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) == - CERT_SYSTEM_STORE_LOCAL_MACHINE && !lstrcmpiW(storeName, rootW)) - return CRYPT_RootOpenStore(hCryptProv, dwFlags); switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) { case CERT_SYSTEM_STORE_LOCAL_MACHINE: root = HKEY_LOCAL_MACHINE; base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH; + /* If the HKLM\Root certs are requested, expressing system certs into the registry */ + if (!lstrcmpiW(storeName, rootW)) + CRYPT_ImportSystemRootCertsToReg(); break; case CERT_SYSTEM_STORE_CURRENT_USER: root = HKEY_CURRENT_USER; -- 2.7.4 From andrey.goosev at gmail.com Sat Oct 29 08:55:18 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Sat, 29 Oct 2016 16:55:18 +0300 Subject: api-ms-win-rtcore-ntuser-private-l1-1-0: Add dll. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: api-ms-win-rtcore-ntuser-private-l1-1-0-Add-dll.patch Type: text/x-patch Size: 4058 bytes Desc: not available URL: From andrey.goosev at gmail.com Sat Oct 29 08:56:11 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Sat, 29 Oct 2016 16:56:11 +0300 Subject: ext-ms-win-ntuser-private-l1-1-1: Add dll. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: ext-ms-win-ntuser-private-l1-1-1-Add-dll.patch Type: text/x-patch Size: 4366 bytes Desc: not available URL: From andrey.goosev at gmail.com Sat Oct 29 08:57:03 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Sat, 29 Oct 2016 16:57:03 +0300 Subject: ext-ms-win-ntuser-rectangle-ext-l1-1-0: Add dll. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: ext-ms-win-ntuser-rectangle-ext-l1-1-0-Add-dll.patch Type: text/x-patch Size: 4225 bytes Desc: not available URL: From andrey.goosev at gmail.com Sat Oct 29 08:57:48 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Sat, 29 Oct 2016 16:57:48 +0300 Subject: ext-ms-win-ntuser-window-l1-1-1: Add dll. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: ext-ms-win-ntuser-window-l1-1-1-Add-dll.patch Type: text/x-patch Size: 6687 bytes Desc: not available URL: From andrey.goosev at gmail.com Sat Oct 29 08:58:34 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Sat, 29 Oct 2016 16:58:34 +0300 Subject: ext-ms-win-rtcore-ntuser-sysparams-l1-1-0: Add dll. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: ext-ms-win-rtcore-ntuser-sysparams-l1-1-0-Add-dll.patch Type: text/x-patch Size: 4772 bytes Desc: not available URL: From nsivov at codeweavers.com Sat Oct 29 12:22:27 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Sat, 29 Oct 2016 20:22:27 +0300 Subject: [v4 PATCH] ucrtbase: Added _sopen_dispatch/_wsopen_dispatch Message-ID: <20161029172227.21725-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- v4: added some tests .../api-ms-win-crt-stdio-l1-1-0.spec | 4 +- dlls/msvcrt/file.c | 40 ++++++++--- dlls/ucrtbase/tests/misc.c | 81 ++++++++++++++++++++++ dlls/ucrtbase/ucrtbase.spec | 4 +- 4 files changed, 114 insertions(+), 15 deletions(-) diff --git a/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec b/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec index 4b8be01..6acd08e 100644 --- a/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec +++ b/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec @@ -87,7 +87,7 @@ @ cdecl _setmaxstdio(long) ucrtbase._setmaxstdio @ cdecl _setmode(long long) ucrtbase._setmode @ varargs _sopen(str long long) ucrtbase._sopen -@ stub _sopen_dispatch +@ cdecl _sopen_dispatch(str long long long ptr long) ucrtbase._sopen_dispatch @ cdecl _sopen_s(ptr str long long long) ucrtbase._sopen_s @ cdecl _tell(long) ucrtbase._tell @ cdecl -ret64 _telli64(long) ucrtbase._telli64 @@ -107,7 +107,7 @@ @ cdecl _wpopen(wstr wstr) ucrtbase._wpopen @ cdecl _write(long ptr long) ucrtbase._write @ varargs _wsopen(wstr long long) ucrtbase._wsopen -@ stub _wsopen_dispatch +@ cdecl _wsopen_dispatch(wstr long long long ptr long) ucrtbase._wsopen_dispatch @ cdecl _wsopen_s(ptr wstr long long long) ucrtbase._wsopen_s @ cdecl _wtempnam(wstr wstr) ucrtbase._wtempnam @ cdecl _wtmpnam(ptr) ucrtbase._wtmpnam diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index 432d5c7..8965156 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -2144,9 +2144,10 @@ static int check_bom(HANDLE h, int oflags, BOOL seek) } /********************************************************************* - * _wsopen_s (MSVCRT.@) + * _wsopen_dispatch (UCRTBASE.@) */ -int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int shflags, int pmode ) +int CDECL MSVCRT__wsopen_dispatch( const MSVCRT_wchar_t* path, int oflags, int shflags, int pmode, + int *fd, int secure ) { DWORD access = 0, creation = 0, attrib; SECURITY_ATTRIBUTES sa; @@ -2154,8 +2155,8 @@ int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int int wxflag; HANDLE hand; - TRACE("fd*: %p :file (%s) oflags: 0x%04x shflags: 0x%04x pmode: 0x%04x\n", - fd, debugstr_w(path), oflags, shflags, pmode); + TRACE("path: (%s) oflags: 0x%04x shflags: 0x%04x pmode: 0x%04x fd*: %p secure: %d\n", + debugstr_w(path), oflags, shflags, pmode, fd, secure); if (!MSVCRT_CHECK_PMT( fd != NULL )) return MSVCRT_EINVAL; @@ -2306,6 +2307,15 @@ int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int return 0; } + +/********************************************************************* + * _wsopen_s (MSVCRT.@) + */ +int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int shflags, int pmode ) +{ + return MSVCRT__wsopen_dispatch( path, oflags, shflags, pmode, fd, 1 ); +} + /********************************************************************* * _wsopen (MSVCRT.@) */ @@ -2325,14 +2335,15 @@ int CDECL MSVCRT__wsopen( const MSVCRT_wchar_t *path, int oflags, int shflags, . else pmode = 0; - MSVCRT__wsopen_s(&fd, path, oflags, shflags, pmode); - return fd; + return MSVCRT__wsopen_dispatch(path, oflags, shflags, pmode, &fd, 0) ? -1 : fd; } + /********************************************************************* - * _sopen_s (MSVCRT.@) + * _sopen_dispatch (UCRTBASE.@) */ -int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, int pmode ) +int CDECL MSVCRT__sopen_dispatch( const char *path, int oflags, int shflags, + int pmode, int *fd, int secure) { MSVCRT_wchar_t *pathW; int ret; @@ -2343,12 +2354,20 @@ int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, i if(!MSVCRT_CHECK_PMT(path && (pathW = msvcrt_wstrdupa(path)))) return MSVCRT_EINVAL; - ret = MSVCRT__wsopen_s(fd, pathW, oflags, shflags, pmode); + ret = MSVCRT__wsopen_dispatch(pathW, oflags, shflags, pmode, fd, secure); MSVCRT_free(pathW); return ret; } /********************************************************************* + * _sopen_s (MSVCRT.@) + */ +int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, int pmode ) +{ + return MSVCRT__sopen_dispatch(path, oflags, shflags, pmode, fd, 1); +} + +/********************************************************************* * _sopen (MSVCRT.@) */ int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... ) @@ -2367,8 +2386,7 @@ int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... ) else pmode = 0; - MSVCRT__sopen_s(&fd, path, oflags, shflags, pmode); - return fd; + return MSVCRT__sopen_dispatch(path, oflags, shflags, pmode, &fd, 0) ? -1 : fd; } /********************************************************************* diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index ad22699..cc82022 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -22,6 +22,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -74,6 +78,8 @@ static _invalid_parameter_handler (CDECL *p__set_thread_local_invalid_parameter_ static _invalid_parameter_handler (CDECL *p__get_thread_local_invalid_parameter_handler)(void); static int (CDECL *p__ltoa_s)(LONG, char*, size_t, int); static char* (CDECL *p__get_narrow_winmain_command_line)(void); +static int (CDECL *p_sopen_dispatch)(const char *, int, int, int, int *, int); +static int (CDECL *p_sopen_s)(int *, const char *, int, int, int); static void test__initialize_onexit_table(void) { @@ -365,10 +371,83 @@ static BOOL init(void) p__get_thread_local_invalid_parameter_handler = (void*)GetProcAddress(module, "_get_thread_local_invalid_parameter_handler"); p__ltoa_s = (void*)GetProcAddress(module, "_ltoa_s"); p__get_narrow_winmain_command_line = (void*)GetProcAddress(GetModuleHandleA("ucrtbase.dll"), "_get_narrow_winmain_command_line"); + p_sopen_dispatch = (void*)GetProcAddress(module, "_sopen_dispatch"); + p_sopen_s = (void*)GetProcAddress(module, "_sopen_s"); return TRUE; } +static void test__sopen_dispatch(void) +{ + int ret, fd; + char *tempf; + + tempf = _tempnam(".", "wne"); + + fd = 0; + ret = p_sopen_dispatch(tempf, _O_CREAT, _SH_DENYWR, 0xff, &fd, 0); + ok(!ret, "got %d\n", ret); + ok(fd > 0, "got fd %d\n", fd); + _close(fd); + unlink(tempf); + + p__set_invalid_parameter_handler(global_invalid_parameter_handler); + + SET_EXPECT(global_invalid_parameter_handler); + fd = 0; + ret = p_sopen_dispatch(tempf, _O_CREAT, _SH_DENYWR, 0xff, &fd, 1); +todo_wine { + ok(ret == EINVAL, "got %d\n", ret); + ok(fd == -1, "got fd %d\n", fd); + CHECK_CALLED(global_invalid_parameter_handler); +} + if (fd > 0) + { + _close(fd); + unlink(tempf); + } + + p__set_invalid_parameter_handler(NULL); + + free(tempf); +} + +static void test__sopen_s(void) +{ + int ret, fd; + char *tempf; + + tempf = _tempnam(".", "wne"); + + fd = 0; + ret = p_sopen_s(&fd, tempf, _O_CREAT, _SH_DENYWR, 0); + ok(!ret, "got %d\n", ret); + ok(fd > 0, "got fd %d\n", fd); + _close(fd); + unlink(tempf); + + /* _open() does not validate pmode */ + fd = _open(tempf, _O_CREAT, 0xff); + ok(fd > 0, "got fd %d\n", fd); + _close(fd); + unlink(tempf); + + p__set_invalid_parameter_handler(global_invalid_parameter_handler); + + /* _sopen_s() invokes invalid parameter handler on invalid pmode */ + SET_EXPECT(global_invalid_parameter_handler); + fd = 0; + ret = p_sopen_s(&fd, tempf, _O_CREAT, _SH_DENYWR, 0xff); +todo_wine { + ok(ret == EINVAL, "got %d\n", ret); + ok(fd == -1, "got fd %d\n", fd); + CHECK_CALLED(global_invalid_parameter_handler); +} + p__set_invalid_parameter_handler(NULL); + + free(tempf); +} + START_TEST(misc) { int arg_c; @@ -389,4 +468,6 @@ START_TEST(misc) test__execute_onexit_table(); test___fpe_flt_rounds(); test__get_narrow_winmain_command_line(arg_v[0]); + test__sopen_dispatch(); + test__sopen_s(); } diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index f0598ce..47608f9 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -1902,7 +1902,7 @@ @ stub _setsystime(ptr long) @ cdecl _sleep(long) MSVCRT__sleep @ varargs _sopen(str long long) MSVCRT__sopen -@ stub _sopen_dispatch +@ cdecl _sopen_dispatch(str long long long ptr long) MSVCRT__sopen_dispatch @ cdecl _sopen_s(ptr str long long long) MSVCRT__sopen_s @ varargs _spawnl(long str str) @ varargs _spawnle(long str str) @@ -2109,7 +2109,7 @@ @ cdecl _wsearchenv_s(wstr wstr ptr long) MSVCRT__wsearchenv_s @ cdecl _wsetlocale(long wstr) MSVCRT__wsetlocale @ varargs _wsopen(wstr long long) MSVCRT__wsopen -@ stub _wsopen_dispatch +@ cdecl _wsopen_dispatch(wstr long long long ptr long) MSVCRT__wsopen_dispatch @ cdecl _wsopen_s(ptr wstr long long long) MSVCRT__wsopen_s @ varargs _wspawnl(long wstr wstr) @ varargs _wspawnle(long wstr wstr) -- 2.10.1 From nsivov at codeweavers.com Sat Oct 29 13:25:54 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Sat, 29 Oct 2016 21:25:54 +0300 Subject: [PATCH] dwrite: Update to IDWriteFontFace4 Message-ID: <20161029182554.23185-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/dwrite/dwrite_private.h | 28 ++-- dlls/dwrite/font.c | 358 +++++++++++++++++++++++-------------------- dlls/dwrite/freetype.c | 44 +++--- dlls/dwrite/main.c | 14 +- dlls/dwrite/opentype.c | 6 +- 5 files changed, 242 insertions(+), 208 deletions(-) diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index cf305e6..dad0f47 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -180,7 +180,7 @@ extern HRESULT get_eudc_fontcollection(IDWriteFactory4*,IDWriteFontCollection**) extern HRESULT get_textanalyzer(IDWriteTextAnalyzer**) DECLSPEC_HIDDEN; extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN; extern HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface) DECLSPEC_HIDDEN; -extern HRESULT create_fontface(const struct fontface_desc*,IDWriteFontFace3**) DECLSPEC_HIDDEN; +extern HRESULT create_fontface(const struct fontface_desc*,IDWriteFontFace4**) DECLSPEC_HIDDEN; extern HRESULT create_font_collection(IDWriteFactory4*,IDWriteFontFileEnumerator*,BOOL,IDWriteFontCollection1**) DECLSPEC_HIDDEN; extern HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc*,IDWriteGlyphRunAnalysis**) DECLSPEC_HIDDEN; extern BOOL is_system_collection(IDWriteFontCollection*) DECLSPEC_HIDDEN; @@ -199,7 +199,7 @@ extern HRESULT create_fontfacereference(IDWriteFactory4*,IDWriteFontFile*,UINT32 IDWriteFontFaceReference**) DECLSPEC_HIDDEN; extern HRESULT factory_get_cached_fontface(IDWriteFactory4*,IDWriteFontFile*const*,UINT32,DWRITE_FONT_SIMULATIONS,IDWriteFontFace**, struct list**) DECLSPEC_HIDDEN; -extern void factory_cache_fontface(struct list*,IDWriteFontFace3*) DECLSPEC_HIDDEN; +extern void factory_cache_fontface(struct list*,IDWriteFontFace4*) DECLSPEC_HIDDEN; /* Opentype font table functions */ struct dwrite_font_props { @@ -229,7 +229,7 @@ extern UINT32 opentype_get_cpal_palettecount(const void*) DECLSPEC_HIDDEN; extern UINT32 opentype_get_cpal_paletteentrycount(const void*) DECLSPEC_HIDDEN; extern HRESULT opentype_get_cpal_entries(const void*,UINT32,UINT32,UINT32,DWRITE_COLOR_F*) DECLSPEC_HIDDEN; extern HRESULT opentype_get_font_signature(struct file_stream_desc*,FONTSIGNATURE*) DECLSPEC_HIDDEN; -extern BOOL opentype_has_vertical_variants(IDWriteFontFace3*) DECLSPEC_HIDDEN; +extern BOOL opentype_has_vertical_variants(IDWriteFontFace4*) DECLSPEC_HIDDEN; struct dwrite_colorglyph { USHORT layer; /* [0, num_layers) index indicating current layer */ @@ -259,7 +259,7 @@ extern WCHAR bidi_get_mirrored_char(WCHAR) DECLSPEC_HIDDEN; /* FreeType integration */ struct dwrite_glyphbitmap { - IDWriteFontFace3 *fontface; + IDWriteFontFace4 *fontface; FLOAT emsize; BOOL nohint; UINT16 index; @@ -272,19 +272,19 @@ struct dwrite_glyphbitmap { extern BOOL init_freetype(void) DECLSPEC_HIDDEN; extern void release_freetype(void) DECLSPEC_HIDDEN; -extern HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace3*,UINT16,UINT16,DWRITE_GLYPH_METRICS*) DECLSPEC_HIDDEN; -extern void freetype_notify_cacheremove(IDWriteFontFace3*) DECLSPEC_HIDDEN; -extern BOOL freetype_is_monospaced(IDWriteFontFace3*) DECLSPEC_HIDDEN; -extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace3*,FLOAT,UINT16 const*,FLOAT const*, DWRITE_GLYPH_OFFSET const*, +extern HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace4*,UINT16,UINT16,DWRITE_GLYPH_METRICS*) DECLSPEC_HIDDEN; +extern void freetype_notify_cacheremove(IDWriteFontFace4*) DECLSPEC_HIDDEN; +extern BOOL freetype_is_monospaced(IDWriteFontFace4*) DECLSPEC_HIDDEN; +extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4*,FLOAT,UINT16 const*,FLOAT const*, DWRITE_GLYPH_OFFSET const*, UINT32,BOOL,IDWriteGeometrySink*) DECLSPEC_HIDDEN; -extern UINT16 freetype_get_glyphcount(IDWriteFontFace3*) DECLSPEC_HIDDEN; -extern void freetype_get_glyphs(IDWriteFontFace3*,INT,UINT32 const*,UINT32,UINT16*) DECLSPEC_HIDDEN; -extern BOOL freetype_has_kerning_pairs(IDWriteFontFace3*) DECLSPEC_HIDDEN; -extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace3*,UINT16,UINT16) DECLSPEC_HIDDEN; +extern UINT16 freetype_get_glyphcount(IDWriteFontFace4*) DECLSPEC_HIDDEN; +extern void freetype_get_glyphs(IDWriteFontFace4*,INT,UINT32 const*,UINT32,UINT16*) DECLSPEC_HIDDEN; +extern BOOL freetype_has_kerning_pairs(IDWriteFontFace4*) DECLSPEC_HIDDEN; +extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace4*,UINT16,UINT16) DECLSPEC_HIDDEN; extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN; extern BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN; -extern INT freetype_get_charmap_index(IDWriteFontFace3*,BOOL*) DECLSPEC_HIDDEN; -extern INT32 freetype_get_glyph_advance(IDWriteFontFace3*,FLOAT,UINT16,DWRITE_MEASURING_MODE) DECLSPEC_HIDDEN; +extern INT freetype_get_charmap_index(IDWriteFontFace4*,BOOL*) DECLSPEC_HIDDEN; +extern INT32 freetype_get_glyph_advance(IDWriteFontFace4*,FLOAT,UINT16,DWRITE_MEASURING_MODE) DECLSPEC_HIDDEN; /* Glyph shaping */ enum SCRIPT_JUSTIFY diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 6b9ee66..75e2e00 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -184,7 +184,7 @@ struct dwrite_colorglyphenum { FLOAT origin_x; /* original run origin */ FLOAT origin_y; - IDWriteFontFace3 *fontface; /* for convenience */ + IDWriteFontFace4 *fontface; /* for convenience */ DWRITE_COLOR_GLYPH_RUN colorrun; /* returned with GetCurrentRun() */ DWRITE_GLYPH_RUN run; /* base run */ UINT32 palette; /* palette index to get layer color from */ @@ -213,7 +213,7 @@ enum fontface_flags { }; struct dwrite_fontface { - IDWriteFontFace3 IDWriteFontFace3_iface; + IDWriteFontFace4 IDWriteFontFace4_iface; LONG ref; IDWriteFontFileStream **streams; @@ -261,9 +261,9 @@ struct dwrite_fontfacereference { IDWriteFactory4 *factory; }; -static inline struct dwrite_fontface *impl_from_IDWriteFontFace3(IDWriteFontFace3 *iface) +static inline struct dwrite_fontface *impl_from_IDWriteFontFace4(IDWriteFontFace4 *iface) { - return CONTAINING_RECORD(iface, struct dwrite_fontface, IDWriteFontFace3_iface); + return CONTAINING_RECORD(iface, struct dwrite_fontface, IDWriteFontFace4_iface); } static inline struct dwrite_font *impl_from_IDWriteFont3(IDWriteFont3 *iface) @@ -336,7 +336,7 @@ static HRESULT set_cached_glyph_metrics(struct dwrite_fontface *fontface, UINT16 return S_OK; } -static void* get_fontface_table(IDWriteFontFace3 *fontface, UINT32 tag, struct dwrite_fonttable *table) +static void* get_fontface_table(IDWriteFontFace4 *fontface, UINT32 tag, struct dwrite_fonttable *table) { HRESULT hr; @@ -344,7 +344,7 @@ static void* get_fontface_table(IDWriteFontFace3 *fontface, UINT32 tag, struct d return table->data; table->exists = FALSE; - hr = IDWriteFontFace3_TryGetFontTable(fontface, tag, (const void**)&table->data, &table->size, &table->context, + hr = IDWriteFontFace4_TryGetFontTable(fontface, tag, (const void**)&table->data, &table->size, &table->context, &table->exists); if (FAILED(hr) || !table->exists) { WARN("Font does not have a %s table\n", debugstr_tag(tag)); @@ -374,29 +374,29 @@ static FLOAT get_font_prop_vec_dotproduct(const struct dwrite_font_propvec *left static inline void* get_fontface_cmap(struct dwrite_fontface *fontface) { - return get_fontface_table(&fontface->IDWriteFontFace3_iface, MS_CMAP_TAG, &fontface->cmap); + return get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_CMAP_TAG, &fontface->cmap); } static inline void* get_fontface_vdmx(struct dwrite_fontface *fontface) { - return get_fontface_table(&fontface->IDWriteFontFace3_iface, MS_VDMX_TAG, &fontface->vdmx); + return get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_VDMX_TAG, &fontface->vdmx); } static inline void* get_fontface_gasp(struct dwrite_fontface *fontface, UINT32 *size) { - void *ptr = get_fontface_table(&fontface->IDWriteFontFace3_iface, MS_GASP_TAG, &fontface->gasp); + void *ptr = get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_GASP_TAG, &fontface->gasp); *size = fontface->gasp.size; return ptr; } static inline void* get_fontface_cpal(struct dwrite_fontface *fontface) { - return get_fontface_table(&fontface->IDWriteFontFace3_iface, MS_CPAL_TAG, &fontface->cpal); + return get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_CPAL_TAG, &fontface->cpal); } static inline void* get_fontface_colr(struct dwrite_fontface *fontface) { - return get_fontface_table(&fontface->IDWriteFontFace3_iface, MS_COLR_TAG, &fontface->colr); + return get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_COLR_TAG, &fontface->colr); } static void release_font_data(struct dwrite_font_data *data) @@ -433,20 +433,21 @@ static void release_fontfamily_data(struct dwrite_fontfamily_data *data) heap_free(data); } -static HRESULT WINAPI dwritefontface_QueryInterface(IDWriteFontFace3 *iface, REFIID riid, void **obj) +static HRESULT WINAPI dwritefontface_QueryInterface(IDWriteFontFace4 *iface, REFIID riid, void **obj) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj); - if (IsEqualIID(riid, &IID_IDWriteFontFace3) || + if (IsEqualIID(riid, &IID_IDWriteFontFace4) || + IsEqualIID(riid, &IID_IDWriteFontFace3) || IsEqualIID(riid, &IID_IDWriteFontFace2) || IsEqualIID(riid, &IID_IDWriteFontFace1) || IsEqualIID(riid, &IID_IDWriteFontFace) || IsEqualIID(riid, &IID_IUnknown)) { *obj = iface; - IDWriteFontFace3_AddRef(iface); + IDWriteFontFace4_AddRef(iface); return S_OK; } @@ -454,17 +455,17 @@ static HRESULT WINAPI dwritefontface_QueryInterface(IDWriteFontFace3 *iface, REF return E_NOINTERFACE; } -static ULONG WINAPI dwritefontface_AddRef(IDWriteFontFace3 *iface) +static ULONG WINAPI dwritefontface_AddRef(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); ULONG ref = InterlockedIncrement(&This->ref); TRACE("(%p)->(%d)\n", This, ref); return ref; } -static ULONG WINAPI dwritefontface_Release(IDWriteFontFace3 *iface) +static ULONG WINAPI dwritefontface_Release(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p)->(%d)\n", This, ref); @@ -473,15 +474,15 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace3 *iface) UINT32 i; if (This->cmap.context) - IDWriteFontFace3_ReleaseFontTable(iface, This->cmap.context); + IDWriteFontFace4_ReleaseFontTable(iface, This->cmap.context); if (This->vdmx.context) - IDWriteFontFace3_ReleaseFontTable(iface, This->vdmx.context); + IDWriteFontFace4_ReleaseFontTable(iface, This->vdmx.context); if (This->gasp.context) - IDWriteFontFace3_ReleaseFontTable(iface, This->gasp.context); + IDWriteFontFace4_ReleaseFontTable(iface, This->gasp.context); if (This->cpal.context) - IDWriteFontFace3_ReleaseFontTable(iface, This->cpal.context); + IDWriteFontFace4_ReleaseFontTable(iface, This->cpal.context); if (This->colr.context) - IDWriteFontFace3_ReleaseFontTable(iface, This->colr.context); + IDWriteFontFace4_ReleaseFontTable(iface, This->colr.context); for (i = 0; i < This->file_count; i++) { if (This->streams[i]) IDWriteFontFileStream_Release(This->streams[i]); @@ -501,17 +502,17 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace3 *iface) return ref; } -static DWRITE_FONT_FACE_TYPE WINAPI dwritefontface_GetType(IDWriteFontFace3 *iface) +static DWRITE_FONT_FACE_TYPE WINAPI dwritefontface_GetType(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)\n", This); return This->type; } -static HRESULT WINAPI dwritefontface_GetFiles(IDWriteFontFace3 *iface, UINT32 *number_of_files, +static HRESULT WINAPI dwritefontface_GetFiles(IDWriteFontFace4 *iface, UINT32 *number_of_files, IDWriteFontFile **fontfiles) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); int i; TRACE("(%p)->(%p %p)\n", This, number_of_files, fontfiles); @@ -532,45 +533,45 @@ static HRESULT WINAPI dwritefontface_GetFiles(IDWriteFontFace3 *iface, UINT32 *n return S_OK; } -static UINT32 WINAPI dwritefontface_GetIndex(IDWriteFontFace3 *iface) +static UINT32 WINAPI dwritefontface_GetIndex(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)\n", This); return This->index; } -static DWRITE_FONT_SIMULATIONS WINAPI dwritefontface_GetSimulations(IDWriteFontFace3 *iface) +static DWRITE_FONT_SIMULATIONS WINAPI dwritefontface_GetSimulations(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)\n", This); return This->simulations; } -static BOOL WINAPI dwritefontface_IsSymbolFont(IDWriteFontFace3 *iface) +static BOOL WINAPI dwritefontface_IsSymbolFont(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)\n", This); return !!(This->flags & FONTFACE_IS_SYMBOL); } -static void WINAPI dwritefontface_GetMetrics(IDWriteFontFace3 *iface, DWRITE_FONT_METRICS *metrics) +static void WINAPI dwritefontface_GetMetrics(IDWriteFontFace4 *iface, DWRITE_FONT_METRICS *metrics) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)->(%p)\n", This, metrics); memcpy(metrics, &This->metrics, sizeof(*metrics)); } -static UINT16 WINAPI dwritefontface_GetGlyphCount(IDWriteFontFace3 *iface) +static UINT16 WINAPI dwritefontface_GetGlyphCount(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)\n", This); return freetype_get_glyphcount(iface); } -static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace3 *iface, +static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace4 *iface, UINT16 const *glyphs, UINT32 glyph_count, DWRITE_GLYPH_METRICS *ret, BOOL is_sideways) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); HRESULT hr; UINT32 i; @@ -598,10 +599,10 @@ static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace3 *ifa return S_OK; } -static HRESULT WINAPI dwritefontface_GetGlyphIndices(IDWriteFontFace3 *iface, UINT32 const *codepoints, +static HRESULT WINAPI dwritefontface_GetGlyphIndices(IDWriteFontFace4 *iface, UINT32 const *codepoints, UINT32 count, UINT16 *glyph_indices) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)->(%p %u %p)\n", This, codepoints, count, glyph_indices); @@ -617,10 +618,10 @@ static HRESULT WINAPI dwritefontface_GetGlyphIndices(IDWriteFontFace3 *iface, UI return S_OK; } -static HRESULT WINAPI dwritefontface_TryGetFontTable(IDWriteFontFace3 *iface, UINT32 table_tag, +static HRESULT WINAPI dwritefontface_TryGetFontTable(IDWriteFontFace4 *iface, UINT32 table_tag, const void **table_data, UINT32 *table_size, void **context, BOOL *exists) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); struct file_stream_desc stream_desc; TRACE("(%p)->(%s %p %p %p %p)\n", This, debugstr_tag(table_tag), table_data, table_size, context, exists); @@ -631,20 +632,20 @@ static HRESULT WINAPI dwritefontface_TryGetFontTable(IDWriteFontFace3 *iface, UI return opentype_get_font_table(&stream_desc, table_tag, table_data, context, table_size, exists); } -static void WINAPI dwritefontface_ReleaseFontTable(IDWriteFontFace3 *iface, void *table_context) +static void WINAPI dwritefontface_ReleaseFontTable(IDWriteFontFace4 *iface, void *table_context) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)->(%p)\n", This, table_context); IDWriteFontFileStream_ReleaseFileFragment(This->streams[0], table_context); } -static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace3 *iface, FLOAT emSize, +static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace4 *iface, FLOAT emSize, UINT16 const *glyphs, FLOAT const* advances, DWRITE_GLYPH_OFFSET const *offsets, UINT32 count, BOOL is_sideways, BOOL is_rtl, IDWriteGeometrySink *sink) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)->(%.2f %p %p %p %u %d %d %p)\n", This, emSize, glyphs, advances, offsets, count, is_sideways, is_rtl, sink); @@ -686,10 +687,10 @@ static DWRITE_RENDERING_MODE fontface_renderingmode_from_measuringmode(DWRITE_ME return mode; } -static HRESULT WINAPI dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace3 *iface, FLOAT emSize, +static HRESULT WINAPI dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace4 *iface, FLOAT emSize, FLOAT ppdip, DWRITE_MEASURING_MODE measuring, IDWriteRenderingParams *params, DWRITE_RENDERING_MODE *mode) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); WORD gasp, *ptr; UINT32 size; FLOAT ppem; @@ -718,11 +719,11 @@ static HRESULT WINAPI dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace return S_OK; } -static HRESULT WINAPI dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace3 *iface, FLOAT emSize, FLOAT pixels_per_dip, +static HRESULT WINAPI dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace4 *iface, FLOAT emSize, FLOAT pixels_per_dip, DWRITE_MATRIX const *transform, DWRITE_FONT_METRICS *metrics) { DWRITE_FONT_METRICS1 metrics1; - HRESULT hr = IDWriteFontFace3_GetGdiCompatibleMetrics(iface, emSize, pixels_per_dip, transform, &metrics1); + HRESULT hr = IDWriteFontFace4_GetGdiCompatibleMetrics(iface, emSize, pixels_per_dip, transform, &metrics1); memcpy(metrics, &metrics1, sizeof(*metrics)); return hr; } @@ -732,11 +733,11 @@ static inline int round_metric(FLOAT metric) return (int)floorf(metric + 0.5f); } -static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace3 *iface, FLOAT emSize, FLOAT ppdip, +static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace4 *iface, FLOAT emSize, FLOAT ppdip, DWRITE_MATRIX const *m, BOOL use_gdi_natural, UINT16 const *glyphs, UINT32 glyph_count, DWRITE_GLYPH_METRICS *metrics, BOOL is_sideways) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); DWRITE_MEASURING_MODE mode; FLOAT scale, size; HRESULT hr; @@ -756,7 +757,7 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac DWRITE_GLYPH_METRICS *ret = metrics + i; DWRITE_GLYPH_METRICS design; - hr = IDWriteFontFace3_GetDesignGlyphMetrics(iface, glyphs + i, 1, &design, is_sideways); + hr = IDWriteFontFace4_GetDesignGlyphMetrics(iface, glyphs + i, 1, &design, is_sideways); if (FAILED(hr)) return hr; @@ -776,17 +777,17 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac return S_OK; } -static void WINAPI dwritefontface1_GetMetrics(IDWriteFontFace3 *iface, DWRITE_FONT_METRICS1 *metrics) +static void WINAPI dwritefontface1_GetMetrics(IDWriteFontFace4 *iface, DWRITE_FONT_METRICS1 *metrics) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)->(%p)\n", This, metrics); *metrics = This->metrics; } -static HRESULT WINAPI dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace3 *iface, FLOAT em_size, FLOAT pixels_per_dip, +static HRESULT WINAPI dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace4 *iface, FLOAT em_size, FLOAT pixels_per_dip, const DWRITE_MATRIX *m, DWRITE_FONT_METRICS1 *metrics) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); const DWRITE_FONT_METRICS1 *design = &This->metrics; UINT16 ascent, descent; FLOAT scale; @@ -839,17 +840,17 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace3 * return S_OK; } -static void WINAPI dwritefontface1_GetCaretMetrics(IDWriteFontFace3 *iface, DWRITE_CARET_METRICS *metrics) +static void WINAPI dwritefontface1_GetCaretMetrics(IDWriteFontFace4 *iface, DWRITE_CARET_METRICS *metrics) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)->(%p)\n", This, metrics); *metrics = This->caret; } -static HRESULT WINAPI dwritefontface1_GetUnicodeRanges(IDWriteFontFace3 *iface, UINT32 max_count, +static HRESULT WINAPI dwritefontface1_GetUnicodeRanges(IDWriteFontFace4 *iface, UINT32 max_count, DWRITE_UNICODE_RANGE *ranges, UINT32 *count) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)->(%u %p %p)\n", This, max_count, ranges, count); @@ -860,17 +861,17 @@ static HRESULT WINAPI dwritefontface1_GetUnicodeRanges(IDWriteFontFace3 *iface, return opentype_cmap_get_unicode_ranges(get_fontface_cmap(This), max_count, ranges, count); } -static BOOL WINAPI dwritefontface1_IsMonospacedFont(IDWriteFontFace3 *iface) +static BOOL WINAPI dwritefontface1_IsMonospacedFont(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)\n", This); return !!(This->flags & FONTFACE_IS_MONOSPACED); } -static HRESULT WINAPI dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace3 *iface, +static HRESULT WINAPI dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace4 *iface, UINT32 glyph_count, UINT16 const *glyphs, INT32 *advances, BOOL is_sideways) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); UINT32 i; TRACE("(%p)->(%u %p %p %d)\n", This, glyph_count, glyphs, advances, is_sideways); @@ -884,11 +885,11 @@ static HRESULT WINAPI dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace3 *i return S_OK; } -static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontFace3 *iface, +static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontFace4 *iface, FLOAT em_size, FLOAT ppdip, const DWRITE_MATRIX *m, BOOL use_gdi_natural, BOOL is_sideways, UINT32 glyph_count, UINT16 const *glyphs, INT32 *advances) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); DWRITE_MEASURING_MODE mode; UINT32 i; @@ -918,10 +919,10 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontF return S_OK; } -static HRESULT WINAPI dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace3 *iface, UINT32 count, +static HRESULT WINAPI dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace4 *iface, UINT32 count, const UINT16 *indices, INT32 *adjustments) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); UINT32 i; TRACE("(%p)->(%u %p %p)\n", This, count, indices, adjustments); @@ -946,14 +947,14 @@ static HRESULT WINAPI dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace3 return S_OK; } -static BOOL WINAPI dwritefontface1_HasKerningPairs(IDWriteFontFace3 *iface) +static BOOL WINAPI dwritefontface1_HasKerningPairs(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)\n", This); return !!(This->flags & FONTFACE_HAS_KERN_PAIRS); } -static HRESULT WINAPI dwritefontface1_GetRecommendedRenderingMode(IDWriteFontFace3 *iface, +static HRESULT WINAPI dwritefontface1_GetRecommendedRenderingMode(IDWriteFontFace4 *iface, FLOAT font_emsize, FLOAT dpiX, FLOAT dpiY, const DWRITE_MATRIX *transform, BOOL is_sideways, DWRITE_OUTLINE_THRESHOLD threshold, DWRITE_MEASURING_MODE measuring_mode, DWRITE_RENDERING_MODE *rendering_mode) { @@ -962,56 +963,56 @@ static HRESULT WINAPI dwritefontface1_GetRecommendedRenderingMode(IDWriteFontFac threshold, measuring_mode, NULL, rendering_mode, &gridfitmode); } -static HRESULT WINAPI dwritefontface1_GetVerticalGlyphVariants(IDWriteFontFace3 *iface, UINT32 glyph_count, +static HRESULT WINAPI dwritefontface1_GetVerticalGlyphVariants(IDWriteFontFace4 *iface, UINT32 glyph_count, const UINT16 *nominal_indices, UINT16 *vertical_indices) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); FIXME("(%p)->(%u %p %p): stub\n", This, glyph_count, nominal_indices, vertical_indices); return E_NOTIMPL; } -static BOOL WINAPI dwritefontface1_HasVerticalGlyphVariants(IDWriteFontFace3 *iface) +static BOOL WINAPI dwritefontface1_HasVerticalGlyphVariants(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)\n", This); return !!(This->flags & FONTFACE_HAS_VERTICAL_VARIANTS); } -static BOOL WINAPI dwritefontface2_IsColorFont(IDWriteFontFace3 *iface) +static BOOL WINAPI dwritefontface2_IsColorFont(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)\n", This); return get_fontface_cpal(This) && get_fontface_colr(This); } -static UINT32 WINAPI dwritefontface2_GetColorPaletteCount(IDWriteFontFace3 *iface) +static UINT32 WINAPI dwritefontface2_GetColorPaletteCount(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)\n", This); return opentype_get_cpal_palettecount(get_fontface_cpal(This)); } -static UINT32 WINAPI dwritefontface2_GetPaletteEntryCount(IDWriteFontFace3 *iface) +static UINT32 WINAPI dwritefontface2_GetPaletteEntryCount(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)\n", This); return opentype_get_cpal_paletteentrycount(get_fontface_cpal(This)); } -static HRESULT WINAPI dwritefontface2_GetPaletteEntries(IDWriteFontFace3 *iface, UINT32 palette_index, +static HRESULT WINAPI dwritefontface2_GetPaletteEntries(IDWriteFontFace4 *iface, UINT32 palette_index, UINT32 first_entry_index, UINT32 entry_count, DWRITE_COLOR_F *entries) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)->(%u %u %u %p)\n", This, palette_index, first_entry_index, entry_count, entries); return opentype_get_cpal_entries(get_fontface_cpal(This), palette_index, first_entry_index, entry_count, entries); } -static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFace3 *iface, FLOAT emSize, +static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFace4 *iface, FLOAT emSize, FLOAT dpiX, FLOAT dpiY, DWRITE_MATRIX const *m, BOOL is_sideways, DWRITE_OUTLINE_THRESHOLD threshold, DWRITE_MEASURING_MODE measuringmode, IDWriteRenderingParams *params, DWRITE_RENDERING_MODE *renderingmode, DWRITE_GRID_FIT_MODE *gridfitmode) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); FLOAT emthreshold; WORD gasp, *ptr; UINT32 size; @@ -1067,84 +1068,84 @@ static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFac return S_OK; } -static HRESULT WINAPI dwritefontface3_GetFontFaceReference(IDWriteFontFace3 *iface, IDWriteFontFaceReference **ref) +static HRESULT WINAPI dwritefontface3_GetFontFaceReference(IDWriteFontFace4 *iface, IDWriteFontFaceReference **ref) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); FIXME("(%p)->(%p): stub\n", This, ref); return E_NOTIMPL; } -static void WINAPI dwritefontface3_GetPanose(IDWriteFontFace3 *iface, DWRITE_PANOSE *panose) +static void WINAPI dwritefontface3_GetPanose(IDWriteFontFace4 *iface, DWRITE_PANOSE *panose) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)->(%p)\n", This, panose); *panose = This->panose; } -static DWRITE_FONT_WEIGHT WINAPI dwritefontface3_GetWeight(IDWriteFontFace3 *iface) +static DWRITE_FONT_WEIGHT WINAPI dwritefontface3_GetWeight(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)\n", This); return This->weight; } -static DWRITE_FONT_STRETCH WINAPI dwritefontface3_GetStretch(IDWriteFontFace3 *iface) +static DWRITE_FONT_STRETCH WINAPI dwritefontface3_GetStretch(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)\n", This); return This->stretch; } -static DWRITE_FONT_STYLE WINAPI dwritefontface3_GetStyle(IDWriteFontFace3 *iface) +static DWRITE_FONT_STYLE WINAPI dwritefontface3_GetStyle(IDWriteFontFace4 *iface) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); TRACE("(%p)\n", This); return This->style; } -static HRESULT WINAPI dwritefontface3_GetFamilyNames(IDWriteFontFace3 *iface, IDWriteLocalizedStrings **names) +static HRESULT WINAPI dwritefontface3_GetFamilyNames(IDWriteFontFace4 *iface, IDWriteLocalizedStrings **names) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); FIXME("(%p)->(%p): stub\n", This, names); return E_NOTIMPL; } -static HRESULT WINAPI dwritefontface3_GetFaceNames(IDWriteFontFace3 *iface, IDWriteLocalizedStrings **names) +static HRESULT WINAPI dwritefontface3_GetFaceNames(IDWriteFontFace4 *iface, IDWriteLocalizedStrings **names) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); FIXME("(%p)->(%p): stub\n", This, names); return E_NOTIMPL; } -static HRESULT WINAPI dwritefontface3_GetInformationalStrings(IDWriteFontFace3 *iface, DWRITE_INFORMATIONAL_STRING_ID stringid, +static HRESULT WINAPI dwritefontface3_GetInformationalStrings(IDWriteFontFace4 *iface, DWRITE_INFORMATIONAL_STRING_ID stringid, IDWriteLocalizedStrings **strings, BOOL *exists) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); FIXME("(%p)->(%u %p %p): stub\n", This, stringid, strings, exists); return E_NOTIMPL; } -static BOOL WINAPI dwritefontface3_HasCharacter(IDWriteFontFace3 *iface, UINT32 ch) +static BOOL WINAPI dwritefontface3_HasCharacter(IDWriteFontFace4 *iface, UINT32 ch) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); UINT16 index; HRESULT hr; TRACE("(%p)->(0x%08x)\n", This, ch); index = 0; - hr = IDWriteFontFace3_GetGlyphIndices(iface, &ch, 1, &index); + hr = IDWriteFontFace4_GetGlyphIndices(iface, &ch, 1, &index); if (FAILED(hr)) return FALSE; return index != 0; } -static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFace3 *iface, FLOAT emSize, FLOAT dpiX, FLOAT dpiY, +static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFace4 *iface, FLOAT emSize, FLOAT dpiX, FLOAT dpiY, DWRITE_MATRIX const *m, BOOL is_sideways, DWRITE_OUTLINE_THRESHOLD threshold, DWRITE_MEASURING_MODE measuring_mode, IDWriteRenderingParams *params, DWRITE_RENDERING_MODE1 *rendering_mode, DWRITE_GRID_FIT_MODE *gridfit_mode) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); FLOAT emthreshold; WORD gasp, *ptr; UINT32 size; @@ -1200,37 +1201,66 @@ static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFac return S_OK; } -static BOOL WINAPI dwritefontface3_IsCharacterLocal(IDWriteFontFace3 *iface, UINT32 ch) +static BOOL WINAPI dwritefontface3_IsCharacterLocal(IDWriteFontFace4 *iface, UINT32 ch) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); FIXME("(%p)->(0x%x): stub\n", This, ch); return FALSE; } -static BOOL WINAPI dwritefontface3_IsGlyphLocal(IDWriteFontFace3 *iface, UINT16 glyph) +static BOOL WINAPI dwritefontface3_IsGlyphLocal(IDWriteFontFace4 *iface, UINT16 glyph) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); FIXME("(%p)->(%u): stub\n", This, glyph); return FALSE; } -static HRESULT WINAPI dwritefontface3_AreCharactersLocal(IDWriteFontFace3 *iface, WCHAR const *text, +static HRESULT WINAPI dwritefontface3_AreCharactersLocal(IDWriteFontFace4 *iface, WCHAR const *text, UINT32 count, BOOL enqueue_if_not, BOOL *are_local) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); FIXME("(%p)->(%s:%u %d %p): stub\n", This, debugstr_wn(text, count), count, enqueue_if_not, are_local); return E_NOTIMPL; } -static HRESULT WINAPI dwritefontface3_AreGlyphsLocal(IDWriteFontFace3 *iface, UINT16 const *glyphs, +static HRESULT WINAPI dwritefontface3_AreGlyphsLocal(IDWriteFontFace4 *iface, UINT16 const *glyphs, UINT32 count, BOOL enqueue_if_not, BOOL *are_local) { - struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); FIXME("(%p)->(%p %u %d %p): stub\n", This, glyphs, count, enqueue_if_not, are_local); return E_NOTIMPL; } -static const IDWriteFontFace3Vtbl dwritefontfacevtbl = { +static HRESULT WINAPI dwritefontface4_GetGlyphImageFormats_(IDWriteFontFace4 *iface, UINT16 glyph, + UINT32 ppem_first, UINT32 ppem_last, DWRITE_GLYPH_IMAGE_FORMATS *formats) +{ + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); + FIXME("(%p)->(%u %u %u %p): stub\n", This, glyph, ppem_first, ppem_last, formats); + return E_NOTIMPL; +} + +static DWRITE_GLYPH_IMAGE_FORMATS WINAPI dwritefontface4_GetGlyphImageFormats(IDWriteFontFace4 *iface) +{ + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); + FIXME("(%p): stub\n", This); + return DWRITE_GLYPH_IMAGE_FORMATS_NONE; +} + +static HRESULT WINAPI dwritefontface4_GetGlyphImageData(IDWriteFontFace4 *iface, UINT16 glyph, + UINT32 ppem, DWRITE_GLYPH_IMAGE_FORMATS format, DWRITE_GLYPH_IMAGE_DATA *data, void **context) +{ + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); + FIXME("(%p)->(%u %u %d %p %p): stub\n", This, glyph, ppem, format, data, context); + return E_NOTIMPL; +} + +static void WINAPI dwritefontface4_ReleaseGlyphImageData(IDWriteFontFace4 *iface, void *context) +{ + struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); + FIXME("(%p)->(%p): stub\n", This, context); +} + +static const IDWriteFontFace4Vtbl dwritefontfacevtbl = { dwritefontface_QueryInterface, dwritefontface_AddRef, dwritefontface_Release, @@ -1279,10 +1309,14 @@ static const IDWriteFontFace3Vtbl dwritefontfacevtbl = { dwritefontface3_IsCharacterLocal, dwritefontface3_IsGlyphLocal, dwritefontface3_AreCharactersLocal, - dwritefontface3_AreGlyphsLocal + dwritefontface3_AreGlyphsLocal, + dwritefontface4_GetGlyphImageFormats_, + dwritefontface4_GetGlyphImageFormats, + dwritefontface4_GetGlyphImageData, + dwritefontface4_ReleaseGlyphImageData }; -static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace3 **fontface) +static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace4 **fontface) { struct dwrite_font_data *data = font->data; struct fontface_desc desc; @@ -1391,7 +1425,7 @@ static DWRITE_FONT_STYLE WINAPI dwritefont_GetStyle(IDWriteFont3 *iface) static BOOL WINAPI dwritefont_IsSymbolFont(IDWriteFont3 *iface) { struct dwrite_font *This = impl_from_IDWriteFont3(iface); - IDWriteFontFace3 *fontface; + IDWriteFontFace4 *fontface; HRESULT hr; TRACE("(%p)\n", This); @@ -1400,7 +1434,7 @@ static BOOL WINAPI dwritefont_IsSymbolFont(IDWriteFont3 *iface) if (FAILED(hr)) return FALSE; - return IDWriteFontFace3_IsSymbolFont(fontface); + return IDWriteFontFace4_IsSymbolFont(fontface); } static HRESULT WINAPI dwritefont_GetFaceNames(IDWriteFont3 *iface, IDWriteLocalizedStrings **names) @@ -1426,7 +1460,7 @@ static HRESULT WINAPI dwritefont_GetInformationalStrings(IDWriteFont3 *iface, return S_OK; if (!data->info_strings[stringid]) { - IDWriteFontFace3 *fontface; + IDWriteFontFace4 *fontface; const void *table_data; BOOL table_exists; void *context; @@ -1437,7 +1471,7 @@ static HRESULT WINAPI dwritefont_GetInformationalStrings(IDWriteFont3 *iface, return hr; table_exists = FALSE; - hr = IDWriteFontFace3_TryGetFontTable(fontface, MS_NAME_TAG, &table_data, &size, &context, &table_exists); + hr = IDWriteFontFace4_TryGetFontTable(fontface, MS_NAME_TAG, &table_data, &size, &context, &table_exists); if (FAILED(hr) || !table_exists) WARN("no NAME table found.\n"); @@ -1445,7 +1479,7 @@ static HRESULT WINAPI dwritefont_GetInformationalStrings(IDWriteFont3 *iface, hr = opentype_get_font_info_strings(table_data, stringid, &data->info_strings[stringid]); if (FAILED(hr) || !data->info_strings[stringid]) return hr; - IDWriteFontFace3_ReleaseFontTable(fontface, context); + IDWriteFontFace4_ReleaseFontTable(fontface, context); } } @@ -1475,7 +1509,7 @@ static void WINAPI dwritefont_GetMetrics(IDWriteFont3 *iface, DWRITE_FONT_METRIC static HRESULT WINAPI dwritefont_HasCharacter(IDWriteFont3 *iface, UINT32 value, BOOL *exists) { struct dwrite_font *This = impl_from_IDWriteFont3(iface); - IDWriteFontFace3 *fontface; + IDWriteFontFace4 *fontface; UINT16 index; HRESULT hr; @@ -1488,7 +1522,7 @@ static HRESULT WINAPI dwritefont_HasCharacter(IDWriteFont3 *iface, UINT32 value, return hr; index = 0; - hr = IDWriteFontFace3_GetGlyphIndices(fontface, &value, 1, &index); + hr = IDWriteFontFace4_GetGlyphIndices(fontface, &value, 1, &index); if (FAILED(hr)) return hr; @@ -1520,7 +1554,7 @@ static void WINAPI dwritefont1_GetPanose(IDWriteFont3 *iface, DWRITE_PANOSE *pan static HRESULT WINAPI dwritefont1_GetUnicodeRanges(IDWriteFont3 *iface, UINT32 max_count, DWRITE_UNICODE_RANGE *ranges, UINT32 *count) { struct dwrite_font *This = impl_from_IDWriteFont3(iface); - IDWriteFontFace3 *fontface; + IDWriteFontFace4 *fontface; HRESULT hr; TRACE("(%p)->(%u %p %p)\n", This, max_count, ranges, count); @@ -1529,13 +1563,13 @@ static HRESULT WINAPI dwritefont1_GetUnicodeRanges(IDWriteFont3 *iface, UINT32 m if (FAILED(hr)) return hr; - return IDWriteFontFace3_GetUnicodeRanges(fontface, max_count, ranges, count); + return IDWriteFontFace4_GetUnicodeRanges(fontface, max_count, ranges, count); } static BOOL WINAPI dwritefont1_IsMonospacedFont(IDWriteFont3 *iface) { struct dwrite_font *This = impl_from_IDWriteFont3(iface); - IDWriteFontFace3 *fontface; + IDWriteFontFace4 *fontface; HRESULT hr; TRACE("(%p)\n", This); @@ -1544,13 +1578,13 @@ static BOOL WINAPI dwritefont1_IsMonospacedFont(IDWriteFont3 *iface) if (FAILED(hr)) return FALSE; - return IDWriteFontFace3_IsMonospacedFont(fontface); + return IDWriteFontFace4_IsMonospacedFont(fontface); } static BOOL WINAPI dwritefont2_IsColorFont(IDWriteFont3 *iface) { struct dwrite_font *This = impl_from_IDWriteFont3(iface); - IDWriteFontFace3 *fontface; + IDWriteFontFace4 *fontface; HRESULT hr; TRACE("(%p)\n", This); @@ -1559,7 +1593,7 @@ static BOOL WINAPI dwritefont2_IsColorFont(IDWriteFont3 *iface) if (FAILED(hr)) return FALSE; - return IDWriteFontFace3_IsColorFont(fontface); + return IDWriteFontFace4_IsColorFont(fontface); } static HRESULT WINAPI dwritefont3_CreateFontFace(IDWriteFont3 *iface, IDWriteFontFace3 **fontface) @@ -1569,7 +1603,7 @@ static HRESULT WINAPI dwritefont3_CreateFontFace(IDWriteFont3 *iface, IDWriteFon TRACE("(%p)->(%p)\n", This, fontface); - hr = get_fontface_from_font(This, fontface); + hr = get_fontface_from_font(This, (IDWriteFontFace4**)fontface); if (hr == S_OK) IDWriteFontFace3_AddRef(*fontface); @@ -4141,7 +4175,7 @@ static HRESULT get_stream_from_file(IDWriteFontFile *file, IDWriteFontFileStream return hr; } -HRESULT create_fontface(const struct fontface_desc *desc, IDWriteFontFace3 **ret) +HRESULT create_fontface(const struct fontface_desc *desc, IDWriteFontFace4 **ret) { struct file_stream_desc stream_desc; struct dwrite_fontface *fontface; @@ -4165,7 +4199,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, IDWriteFontFace3 **ret return E_OUTOFMEMORY; } - fontface->IDWriteFontFace3_iface.lpVtbl = &dwritefontfacevtbl; + fontface->IDWriteFontFace4_iface.lpVtbl = &dwritefontfacevtbl; fontface->ref = 1; fontface->type = desc->face_type; fontface->file_count = desc->files_number; @@ -4186,7 +4220,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, IDWriteFontFace3 **ret for (i = 0; i < fontface->file_count; i++) { hr = get_stream_from_file(desc->files[i], &fontface->streams[i]); if (FAILED(hr)) { - IDWriteFontFace3_Release(&fontface->IDWriteFontFace3_iface); + IDWriteFontFace4_Release(&fontface->IDWriteFontFace4_iface); return hr; } @@ -4207,14 +4241,14 @@ HRESULT create_fontface(const struct fontface_desc *desc, IDWriteFontFace3 **ret } fontface->flags = 0; - fontface->charmap = freetype_get_charmap_index(&fontface->IDWriteFontFace3_iface, &is_symbol); + fontface->charmap = freetype_get_charmap_index(&fontface->IDWriteFontFace4_iface, &is_symbol); if (is_symbol) fontface->flags |= FONTFACE_IS_SYMBOL; - if (freetype_has_kerning_pairs(&fontface->IDWriteFontFace3_iface)) + if (freetype_has_kerning_pairs(&fontface->IDWriteFontFace4_iface)) fontface->flags |= FONTFACE_HAS_KERN_PAIRS; - if (freetype_is_monospaced(&fontface->IDWriteFontFace3_iface)) + if (freetype_is_monospaced(&fontface->IDWriteFontFace4_iface)) fontface->flags |= FONTFACE_IS_MONOSPACED; - if (opentype_has_vertical_variants(&fontface->IDWriteFontFace3_iface)) + if (opentype_has_vertical_variants(&fontface->IDWriteFontFace4_iface)) fontface->flags |= FONTFACE_HAS_VERTICAL_VARIANTS; /* Font properties are reused from font object when 'normal' face creation path is used: @@ -4234,7 +4268,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, IDWriteFontFace3 **ret hr = init_font_data(desc, &names, &data); if (FAILED(hr)) { - IDWriteFontFace3_Release(&fontface->IDWriteFontFace3_iface); + IDWriteFontFace4_Release(&fontface->IDWriteFontFace4_iface); return hr; } @@ -4247,7 +4281,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, IDWriteFontFace3 **ret release_font_data(data); } - *ret = &fontface->IDWriteFontFace3_iface; + *ret = &fontface->IDWriteFontFace4_iface; return S_OK; } @@ -4684,7 +4718,7 @@ static ULONG WINAPI glyphrunanalysis_Release(IDWriteGlyphRunAnalysis *iface) static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *analysis, RECT *bounds) { struct dwrite_glyphbitmap glyph_bitmap; - IDWriteFontFace3 *fontface3; + IDWriteFontFace4 *fontface3; D2D_POINT_2F origin; BOOL is_rtl; HRESULT hr; @@ -4698,9 +4732,9 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a if (analysis->run.isSideways) FIXME("sideways runs are not supported.\n"); - hr = IDWriteFontFace_QueryInterface(analysis->run.fontFace, &IID_IDWriteFontFace3, (void**)&fontface3); + hr = IDWriteFontFace_QueryInterface(analysis->run.fontFace, &IID_IDWriteFontFace4, (void**)&fontface3); if (FAILED(hr)) - WARN("failed to get IDWriteFontFace3, 0x%08x\n", hr); + WARN("failed to get IDWriteFontFace4, 0x%08x\n", hr); /* Start with empty bounds at (0,0) origin, returned bounds are not translated back to (0,0), e.g. for RTL run negative left bound is returned, same goes for vertical direction - top bound will be negative @@ -4738,7 +4772,7 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a origin.y += advance->y; } - IDWriteFontFace3_Release(fontface3); + IDWriteFontFace4_Release(fontface3); /* translate to given run origin */ OffsetRect(&analysis->bounds, analysis->origin.x, analysis->origin.y); @@ -4789,16 +4823,16 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW { static const BYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; struct dwrite_glyphbitmap glyph_bitmap; - IDWriteFontFace3 *fontface2; + IDWriteFontFace4 *fontface2; D2D_POINT_2F origin; UINT32 i, size; BOOL is_rtl; HRESULT hr; RECT *bbox; - hr = IDWriteFontFace_QueryInterface(analysis->run.fontFace, &IID_IDWriteFontFace3, (void**)&fontface2); + hr = IDWriteFontFace_QueryInterface(analysis->run.fontFace, &IID_IDWriteFontFace4, (void**)&fontface2); if (FAILED(hr)) { - WARN("failed to get IDWriteFontFace3, 0x%08x\n", hr); + WARN("failed to get IDWriteFontFace4, 0x%08x\n", hr); return; } @@ -4900,7 +4934,7 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW origin.y += advance->y; } - IDWriteFontFace3_Release(fontface2); + IDWriteFontFace4_Release(fontface2); analysis->flags |= RUNANALYSIS_BITMAP_READY; @@ -5226,8 +5260,8 @@ static ULONG WINAPI colorglyphenum_Release(IDWriteColorGlyphRunEnumerator *iface heap_free(This->glyphindices); heap_free(This->glyphs); if (This->colr.context) - IDWriteFontFace3_ReleaseFontTable(This->fontface, This->colr.context); - IDWriteFontFace3_Release(This->fontface); + IDWriteFontFace4_ReleaseFontTable(This->fontface, This->colr.context); + IDWriteFontFace4_Release(This->fontface); heap_free(This); } @@ -5301,7 +5335,7 @@ static BOOL colorglyphenum_build_color_run(struct dwrite_colorglyphenum *glyphen /* use foreground color or request one from the font */ memset(&colorrun->runColor, 0, sizeof(colorrun->runColor)); if (colorrun->paletteIndex != 0xffff) { - HRESULT hr = IDWriteFontFace3_GetPaletteEntries(glyphenum->fontface, glyphenum->palette, colorrun->paletteIndex, + HRESULT hr = IDWriteFontFace4_GetPaletteEntries(glyphenum->fontface, glyphenum->palette, colorrun->paletteIndex, 1, &colorrun->runColor); if (FAILED(hr)) WARN("failed to get palette entry, fontface %p, palette %u, index %u, 0x%08x\n", glyphenum->fontface, @@ -5384,19 +5418,19 @@ HRESULT create_colorglyphenum(FLOAT originX, FLOAT originY, const DWRITE_GLYPH_R { struct dwrite_colorglyphenum *colorglyphenum; BOOL colorfont, has_colored_glyph; - IDWriteFontFace3 *fontface3; + IDWriteFontFace4 *fontface3; HRESULT hr; UINT32 i; *ret = NULL; - hr = IDWriteFontFace_QueryInterface(run->fontFace, &IID_IDWriteFontFace3, (void**)&fontface3); + hr = IDWriteFontFace_QueryInterface(run->fontFace, &IID_IDWriteFontFace4, (void**)&fontface3); if (FAILED(hr)) { - WARN("failed to get IDWriteFontFace3, 0x%08x\n", hr); + WARN("failed to get IDWriteFontFace4, 0x%08x\n", hr); return hr; } - colorfont = IDWriteFontFace3_IsColorFont(fontface3) && IDWriteFontFace3_GetColorPaletteCount(fontface3) > palette; + colorfont = IDWriteFontFace4_IsColorFont(fontface3) && IDWriteFontFace4_GetColorPaletteCount(fontface3) > palette; if (!colorfont) { hr = DWRITE_E_NOCOLOR; goto failed; @@ -5472,14 +5506,14 @@ HRESULT create_colorglyphenum(FLOAT originX, FLOAT originY, const DWRITE_GLYPH_R switch (measuring_mode) { case DWRITE_MEASURING_MODE_NATURAL: - hr = IDWriteFontFace3_GetDesignGlyphAdvances(fontface3, 1, run->glyphIndices + i, &a, run->isSideways); + hr = IDWriteFontFace4_GetDesignGlyphAdvances(fontface3, 1, run->glyphIndices + i, &a, run->isSideways); if (FAILED(hr)) a = 0; colorglyphenum->advances[i] = get_scaled_advance_width(a, run->fontEmSize, &metrics); break; case DWRITE_MEASURING_MODE_GDI_CLASSIC: case DWRITE_MEASURING_MODE_GDI_NATURAL: - hr = IDWriteFontFace3_GetGdiCompatibleGlyphAdvances(fontface3, run->fontEmSize, 1.0f, transform, + hr = IDWriteFontFace4_GetGdiCompatibleGlyphAdvances(fontface3, run->fontEmSize, 1.0f, transform, measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL, run->isSideways, 1, run->glyphIndices + i, &a); if (FAILED(hr)) colorglyphenum->advances[i] = 0.0f; @@ -5496,7 +5530,7 @@ HRESULT create_colorglyphenum(FLOAT originX, FLOAT originY, const DWRITE_GLYPH_R return S_OK; failed: - IDWriteFontFace3_Release(fontface3); + IDWriteFontFace4_Release(fontface3); return hr; } @@ -5570,7 +5604,7 @@ static HRESULT WINAPI fontfacereference_CreateFontFaceWithSimulations(IDWriteFon hr = IDWriteFactory4_CreateFontFace(This->factory, face_type, 1, &This->file, This->index, simulations, &fontface); if (SUCCEEDED(hr)) { - hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace3, (void**)ret); + hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace4, (void**)ret); IDWriteFontFace_Release(fontface); } diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index b6d785f..3179438 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -222,14 +222,14 @@ void release_freetype(void) pFT_Done_FreeType(library); } -void freetype_notify_cacheremove(IDWriteFontFace3 *fontface) +void freetype_notify_cacheremove(IDWriteFontFace4 *fontface) { EnterCriticalSection(&freetype_cs); pFTC_Manager_RemoveFaceID(cache_manager, fontface); LeaveCriticalSection(&freetype_cs); } -HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace3 *fontface, UINT16 unitsperEm, UINT16 glyph, DWRITE_GLYPH_METRICS *ret) +HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace4 *fontface, UINT16 unitsperEm, UINT16 glyph, DWRITE_GLYPH_METRICS *ret) { FTC_ScalerRec scaler; FT_Size size; @@ -260,7 +260,7 @@ HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace3 *fontface, UINT16 uni return S_OK; } -BOOL freetype_is_monospaced(IDWriteFontFace3 *fontface) +BOOL freetype_is_monospaced(IDWriteFontFace4 *fontface) { BOOL is_monospaced = FALSE; FT_Face face; @@ -417,7 +417,7 @@ static void decompose_outline(FT_Outline *outline, FLOAT xoffset, FLOAT yoffset, ID2D1SimplifiedGeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED); } -HRESULT freetype_get_glyphrun_outline(IDWriteFontFace3 *fontface, FLOAT emSize, UINT16 const *glyphs, FLOAT const *advances, +HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, FLOAT emSize, UINT16 const *glyphs, FLOAT const *advances, DWRITE_GLYPH_OFFSET const *offsets, UINT32 count, BOOL is_rtl, IDWriteGeometrySink *sink) { FTC_ScalerRec scaler; @@ -430,7 +430,7 @@ HRESULT freetype_get_glyphrun_outline(IDWriteFontFace3 *fontface, FLOAT emSize, ID2D1SimplifiedGeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING); - simulations = IDWriteFontFace3_GetSimulations(fontface); + simulations = IDWriteFontFace4_GetSimulations(fontface); scaler.face_id = fontface; scaler.width = emSize; @@ -485,7 +485,7 @@ HRESULT freetype_get_glyphrun_outline(IDWriteFontFace3 *fontface, FLOAT emSize, return hr; } -UINT16 freetype_get_glyphcount(IDWriteFontFace3 *fontface) +UINT16 freetype_get_glyphcount(IDWriteFontFace4 *fontface) { UINT16 count = 0; FT_Face face; @@ -498,7 +498,7 @@ UINT16 freetype_get_glyphcount(IDWriteFontFace3 *fontface) return count; } -void freetype_get_glyphs(IDWriteFontFace3 *fontface, INT charmap, UINT32 const *codepoints, UINT32 count, +void freetype_get_glyphs(IDWriteFontFace4 *fontface, INT charmap, UINT32 const *codepoints, UINT32 count, UINT16 *glyphs) { UINT32 i; @@ -519,7 +519,7 @@ void freetype_get_glyphs(IDWriteFontFace3 *fontface, INT charmap, UINT32 const * LeaveCriticalSection(&freetype_cs); } -BOOL freetype_has_kerning_pairs(IDWriteFontFace3 *fontface) +BOOL freetype_has_kerning_pairs(IDWriteFontFace4 *fontface) { BOOL has_kerning_pairs = FALSE; FT_Face face; @@ -532,7 +532,7 @@ BOOL freetype_has_kerning_pairs(IDWriteFontFace3 *fontface) return has_kerning_pairs; } -INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace3 *fontface, UINT16 left, UINT16 right) +INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace4 *fontface, UINT16 left, UINT16 right) { INT32 adjustment = 0; FT_Face face; @@ -559,7 +559,7 @@ static inline void ft_matrix_from_dwrite_matrix(const DWRITE_MATRIX *m, FT_Matri } /* Should be used only while holding 'freetype_cs' */ -static BOOL is_face_scalable(IDWriteFontFace3 *fontface) +static BOOL is_face_scalable(IDWriteFontFace4 *fontface) { FT_Face face; if (pFTC_Manager_LookupFace(cache_manager, fontface, &face) == 0) @@ -749,7 +749,7 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) return ret; } -INT freetype_get_charmap_index(IDWriteFontFace3 *fontface, BOOL *is_symbol) +INT freetype_get_charmap_index(IDWriteFontFace4 *fontface, BOOL *is_symbol) { INT charmap_index = -1; FT_Face face; @@ -781,7 +781,7 @@ INT freetype_get_charmap_index(IDWriteFontFace3 *fontface, BOOL *is_symbol) return charmap_index; } -INT32 freetype_get_glyph_advance(IDWriteFontFace3 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode) +INT32 freetype_get_glyph_advance(IDWriteFontFace4 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode) { FTC_ImageTypeRec imagetype; FT_Glyph glyph; @@ -815,43 +815,43 @@ void release_freetype(void) { } -void freetype_notify_cacheremove(IDWriteFontFace3 *fontface) +void freetype_notify_cacheremove(IDWriteFontFace4 *fontface) { } -HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace3 *fontface, UINT16 unitsperEm, UINT16 glyph, DWRITE_GLYPH_METRICS *ret) +HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace4 *fontface, UINT16 unitsperEm, UINT16 glyph, DWRITE_GLYPH_METRICS *ret) { return E_NOTIMPL; } -BOOL freetype_is_monospaced(IDWriteFontFace3 *fontface) +BOOL freetype_is_monospaced(IDWriteFontFace4 *fontface) { return FALSE; } -HRESULT freetype_get_glyphrun_outline(IDWriteFontFace3 *fontface, FLOAT emSize, UINT16 const *glyphs, FLOAT const *advances, +HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, FLOAT emSize, UINT16 const *glyphs, FLOAT const *advances, DWRITE_GLYPH_OFFSET const *offsets, UINT32 count, BOOL is_rtl, IDWriteGeometrySink *sink) { return E_NOTIMPL; } -UINT16 freetype_get_glyphcount(IDWriteFontFace3 *fontface) +UINT16 freetype_get_glyphcount(IDWriteFontFace4 *fontface) { return 0; } -void freetype_get_glyphs(IDWriteFontFace3 *fontface, INT charmap, UINT32 const *codepoints, UINT32 count, +void freetype_get_glyphs(IDWriteFontFace4 *fontface, INT charmap, UINT32 const *codepoints, UINT32 count, UINT16 *glyphs) { memset(glyphs, 0, count * sizeof(*glyphs)); } -BOOL freetype_has_kerning_pairs(IDWriteFontFace3 *fontface) +BOOL freetype_has_kerning_pairs(IDWriteFontFace4 *fontface) { return FALSE; } -INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace3 *fontface, UINT16 left, UINT16 right) +INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace4 *fontface, UINT16 left, UINT16 right) { return 0; } @@ -866,13 +866,13 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) return FALSE; } -INT freetype_get_charmap_index(IDWriteFontFace3 *fontface, BOOL *is_symbol) +INT freetype_get_charmap_index(IDWriteFontFace4 *fontface, BOOL *is_symbol) { *is_symbol = FALSE; return -1; } -INT32 freetype_get_glyph_advance(IDWriteFontFace3 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode) +INT32 freetype_get_glyph_advance(IDWriteFontFace4 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode) { return 0; } diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index cf9117a..641e808 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -508,7 +508,7 @@ struct collectionloader struct fontfacecached { struct list entry; - IDWriteFontFace3 *fontface; + IDWriteFontFace4 *fontface; }; struct fileloader @@ -544,7 +544,7 @@ static void release_fontface_cache(struct list *fontfaces) struct fontfacecached *fontface, *fontface2; LIST_FOR_EACH_ENTRY_SAFE(fontface, fontface2, fontfaces, struct fontfacecached, entry) { list_remove(&fontface->entry); - IDWriteFontFace3_Release(fontface->fontface); + IDWriteFontFace4_Release(fontface->fontface); heap_free(fontface); } } @@ -835,14 +835,14 @@ HRESULT factory_get_cached_fontface(IDWriteFactory4 *iface, IDWriteFontFile * co const void *cached_key; IDWriteFontFile *file; - cached_face_index = IDWriteFontFace3_GetIndex(cached->fontface); - cached_simulations = IDWriteFontFace3_GetSimulations(cached->fontface); + cached_face_index = IDWriteFontFace4_GetIndex(cached->fontface); + cached_simulations = IDWriteFontFace4_GetSimulations(cached->fontface); /* skip earlier */ if (cached_face_index != index || cached_simulations != simulations) continue; - hr = IDWriteFontFace3_GetFiles(cached->fontface, &count, &file); + hr = IDWriteFontFace4_GetFiles(cached->fontface, &count, &file); if (FAILED(hr)) return hr; @@ -861,7 +861,7 @@ HRESULT factory_get_cached_fontface(IDWriteFactory4 *iface, IDWriteFontFile * co return S_FALSE; } -void factory_cache_fontface(struct list *fontfaces, IDWriteFontFace3 *fontface) +void factory_cache_fontface(struct list *fontfaces, IDWriteFontFace4 *fontface) { struct fontfacecached *cached; @@ -883,7 +883,7 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory4 *iface, DWRITE_FONT_FACE_TYPE face_type; struct fontface_desc desc; struct list *fontfaces; - IDWriteFontFace3 *face; + IDWriteFontFace4 *face; BOOL is_supported; UINT32 count; HRESULT hr; diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index b38b5a2..3412e66 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -1932,7 +1932,7 @@ HRESULT opentype_get_font_signature(struct file_stream_desc *stream_desc, FONTSI return hr; } -BOOL opentype_has_vertical_variants(IDWriteFontFace3 *fontface) +BOOL opentype_has_vertical_variants(IDWriteFontFace4 *fontface) { const OT_FeatureList *featurelist; const OT_LookupList *lookup_list; @@ -1944,7 +1944,7 @@ BOOL opentype_has_vertical_variants(IDWriteFontFace3 *fontface) HRESULT hr; UINT16 i; - hr = IDWriteFontFace3_TryGetFontTable(fontface, MS_GSUB_TAG, &data, &size, &context, &exists); + hr = IDWriteFontFace4_TryGetFontTable(fontface, MS_GSUB_TAG, &data, &size, &context, &exists); if (FAILED(hr) || !exists) return FALSE; @@ -2002,7 +2002,7 @@ BOOL opentype_has_vertical_variants(IDWriteFontFace3 *fontface) } } - IDWriteFontFace3_ReleaseFontTable(fontface, context); + IDWriteFontFace4_ReleaseFontTable(fontface, context); return ret; } -- 2.10.1 From 00cpxxx at gmail.com Sat Oct 29 19:26:43 2016 From: 00cpxxx at gmail.com (Bruno Jesus) Date: Sat, 29 Oct 2016 22:26:43 -0200 Subject: [PATCH] ws2_32: Fix the default behavior of IPV6_V6ONLY Message-ID: <20161030002643.13431-1-00cpxxx@gmail.com> From: Roman Pišl Signed-off-by: Roman Pišl Signed-off-by: Bruno Jesus <00cpxxx at gmail.com> --- dlls/ws2_32/socket.c | 29 +++++++-------- dlls/ws2_32/tests/sock.c | 91 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 88 insertions(+), 32 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 3d9a99b..8510034 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3240,20 +3240,6 @@ int WINAPI WS_bind(SOCKET s, const struct WS_sockaddr* name, int namelen) } else { -#ifdef IPV6_V6ONLY - const struct sockaddr_in6 *in6 = (const struct sockaddr_in6*) &uaddr; - if (name->sa_family == WS_AF_INET6 && - !memcmp(&in6->sin6_addr, &in6addr_any, sizeof(struct in6_addr))) - { - int enable = 1; - if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable)) == -1) - { - release_sock_fd( s, fd ); - SetLastError(WSAEAFNOSUPPORT); - return SOCKET_ERROR; - } - } -#endif if (name->sa_family == WS_AF_INET) { struct sockaddr_in *in4 = (struct sockaddr_in*) &uaddr; @@ -7241,6 +7227,21 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, TRACE("\tcreated %04lx\n", ret ); if (ipxptype > 0) set_ipx_packettype(ret, ipxptype); + +#ifdef IPV6_V6ONLY + if (unixaf == AF_INET6) + { + int fd = get_sock_fd(ret, 0, NULL); + if (fd != -1) + { + /* IPV6_V6ONLY is set by default on Windows */ + int enable = 1; + if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable))) + WARN("\tsetting IPV6_V6ONLY failed - errno = %i\n", errno); + release_sock_fd(ret, fd); + } + } +#endif return ret; } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index a144bd3..c3de50b 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1732,7 +1732,7 @@ static void test_so_reuseaddr(void) DWORD err; saddr.sin_family = AF_INET; - saddr.sin_port = htons(9375); + saddr.sin_port = htons(SERVERPORT+1); saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); s1=socket(AF_INET, SOCK_STREAM, 0); @@ -6105,11 +6105,10 @@ end: static void test_ipv6only(void) { - SOCKET v4 = INVALID_SOCKET, - v6 = INVALID_SOCKET; + SOCKET v4, v6; struct sockaddr_in sin4; struct sockaddr_in6 sin6; - int ret; + int ret, enabled, len = sizeof(enabled); memset(&sin4, 0, sizeof(sin4)); sin4.sin_family = AF_INET; @@ -6120,27 +6119,83 @@ static void test_ipv6only(void) sin6.sin6_port = htons(SERVERPORT); v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); - if (v6 == INVALID_SOCKET) { - skip("Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n", - WSAGetLastError(), WSAEAFNOSUPPORT); + if (v6 == INVALID_SOCKET) + { + skip("Could not create IPv6 socket (LastError: %d)\n", WSAGetLastError()); goto end; } + + enabled = 2; + ret = getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len); + ok(!ret, "getsockopt(IPV6_ONLY) failed (LastError: %d)\n", WSAGetLastError()); + ok(enabled == 1, "expected 1, got %d\n", enabled); + ret = bind(v6, (struct sockaddr*)&sin6, sizeof(sin6)); - if (ret) { - skip("Could not bind IPv6 address (LastError: %d).\n", - WSAGetLastError()); + if (ret) + { + skip("Could not bind IPv6 address (LastError: %d)\n", WSAGetLastError()); goto end; } v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (v4 == INVALID_SOCKET) { - skip("Could not create IPv4 socket (LastError: %d).\n", - WSAGetLastError()); - goto end; - } + ok(v4 != INVALID_SOCKET, "Could not create IPv6 socket (LastError: %d)\n", WSAGetLastError()); + + /* bind on IPv4 socket should succeed - IPV6_V6ONLY is enabled by default */ + ret = bind(v4, (struct sockaddr*)&sin4, sizeof(sin4)); + ok(!ret, "Could not bind IPv4 address (LastError: %d)\n", WSAGetLastError()); + + closesocket(v4); + closesocket(v6); + + /* Test again, this time disabling IPV6_V6ONLY. */ + sin4.sin_port = htons(SERVERPORT+2); + sin6.sin6_port = htons(SERVERPORT+2); + + v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + ok(v6 != INVALID_SOCKET, "Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n", + WSAGetLastError(), WSAEAFNOSUPPORT); + + enabled = 0; + ret = setsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len); + ok(!ret, "Could not disable IPV6_V6ONLY (LastError: %d).\n", WSAGetLastError()); + + enabled = 2; + ret = getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len); + ok(!ret, "getsockopt(IPV6_ONLY) failed (LastError: %d)\n", WSAGetLastError()); + ok(!enabled, "expected 0, got %d\n", enabled); + + /* + Observaition: + On Windows, bind on both IPv4 and IPv6 with IPV6_V6ONLY disabled succeeds by default. + Application must set SO_EXCLUSIVEADDRUSE on first socket to disallow another successful bind. + In general, a standard application should not use SO_REUSEADDR. + Setting both SO_EXCLUSIVEADDRUSE and SO_REUSEADDR on the same socket is not possible in + either order, the later setsockopt call always fails. + */ + enabled = 1; + ret = setsockopt(v6, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&enabled, len); + ok(!ret, "Could not set SO_EXCLUSIVEADDRUSE on IPv6 socket (LastError: %d)\n", WSAGetLastError()); + + ret = bind(v6, (struct sockaddr*)&sin6, sizeof(sin6)); + ok(!ret, "Could not bind IPv6 address (LastError: %d)\n", WSAGetLastError()); + + enabled = 2; + len = sizeof(enabled); + getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len); + ok(!ret, "getsockopt(IPV6_ONLY) failed (LastError: %d)\n", WSAGetLastError()); + ok(!enabled, "IPV6_V6ONLY is enabled after bind\n"); + + v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + ok(v4 != INVALID_SOCKET, "Could not create IPv4 socket (LastError: %d)\n", WSAGetLastError()); + + enabled = 1; + ret = setsockopt(v4, SOL_SOCKET, SO_REUSEADDR, (char*)&enabled, len); + ok(!ret, "Could not set SO_REUSEADDR on IPv4 socket (LastError: %d)\n", WSAGetLastError()); + + WSASetLastError(0xdeadbeef); ret = bind(v4, (struct sockaddr*)&sin4, sizeof(sin4)); - ok(!ret, "Could not bind IPv4 address (LastError: %d; %d expected if IPv6 binds to IPv4 as well).\n", - WSAGetLastError(), WSAEADDRINUSE); + ok(ret, "bind succeeded unexpectedly for the IPv4 socket\n"); + ok(WSAGetLastError() == WSAEACCES, "Expected 10013, got %d\n", WSAGetLastError()); end: if (v4 != INVALID_SOCKET) @@ -8024,7 +8079,7 @@ static void test_TransmitFile(void) /* Setup a properly connected socket for transfers */ memset(&bindAddress, 0, sizeof(bindAddress)); bindAddress.sin_family = AF_INET; - bindAddress.sin_port = htons(9375); + bindAddress.sin_port = htons(SERVERPORT+1); bindAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); iret = bind(server, (struct sockaddr*)&bindAddress, sizeof(bindAddress)); if (iret != 0) -- 2.9.3 From 00cpxxx at gmail.com Sat Oct 29 20:13:25 2016 From: 00cpxxx at gmail.com (Bruno Jesus) Date: Sat, 29 Oct 2016 23:13:25 -0200 Subject: [PATCH] xinput1_3: Prefer builtin DLL Message-ID: <20161030011325.14199-1-00cpxxx@gmail.com> Despite fixing a bug I can't see any reason to prefer native version since it is probably never going to work anyway. Fixes bug https://bugs.winehq.org/show_bug.cgi?id=41428 Signed-off-by: Bruno Jesus <00cpxxx at gmail.com> --- dlls/xinput1_3/xinput1_3_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/dlls/xinput1_3/xinput1_3_main.c b/dlls/xinput1_3/xinput1_3_main.c index 04732eb..5f88ca1 100644 --- a/dlls/xinput1_3/xinput1_3_main.c +++ b/dlls/xinput1_3/xinput1_3_main.c @@ -43,8 +43,6 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { switch(reason) { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(inst); break; -- 2.9.3 From nsivov at codeweavers.com Sun Oct 30 03:05:28 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Sun, 30 Oct 2016 11:05:28 +0300 Subject: [PATCH] xmllite: Store and return MultiLanguage reader property Message-ID: <20161030080528.29505-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/xmllite/reader.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c index b6fce80..deab301 100644 --- a/dlls/xmllite/reader.c +++ b/dlls/xmllite/reader.c @@ -244,6 +244,7 @@ typedef struct XmlNodeType nodetype; DtdProcessing dtdmode; IXmlResolver *resolver; + IUnknown *mlang; UINT line, pos; /* reader position in XML stream */ struct list attrs; /* attributes list for current node */ struct attribute *attr; /* current attribute */ @@ -2474,6 +2475,7 @@ static ULONG WINAPI xmlreader_Release(IXmlReader *iface) IMalloc *imalloc = This->imalloc; if (This->input) IUnknown_Release(&This->input->IXmlReaderInput_iface); if (This->resolver) IXmlResolver_Release(This->resolver); + if (This->mlang) IUnknown_Release(This->mlang); reader_clear_attrs(This); reader_clear_elements(This); reader_free_strvalues(This); @@ -2558,6 +2560,11 @@ static HRESULT WINAPI xmlreader_GetProperty(IXmlReader* iface, UINT property, LO switch (property) { + case XmlReaderProperty_MultiLanguage: + *value = (LONG_PTR)This->mlang; + if (This->mlang) + IUnknown_AddRef(This->mlang); + break; case XmlReaderProperty_XmlResolver: *value = (LONG_PTR)This->resolver; if (This->resolver) @@ -2586,8 +2593,13 @@ static HRESULT WINAPI xmlreader_SetProperty(IXmlReader* iface, UINT property, LO switch (property) { case XmlReaderProperty_MultiLanguage: - if (value) - FIXME("Ignoring MultiLanguage %lx\n", value); + if (This->mlang) + IUnknown_Release(This->mlang); + This->mlang = (IUnknown*)value; + if (This->mlang) + IUnknown_AddRef(This->mlang); + if (This->mlang) + FIXME("Ignoring MultiLanguage %p\n", This->mlang); break; case XmlReaderProperty_XmlResolver: if (This->resolver) @@ -2996,6 +3008,7 @@ HRESULT WINAPI CreateXmlReader(REFIID riid, void **obj, IMalloc *imalloc) reader->resumestate = XmlReadResumeState_Initial; reader->dtdmode = DtdProcessing_Prohibit; reader->resolver = NULL; + reader->mlang = NULL; reader->line = reader->pos = 0; reader->imalloc = imalloc; if (imalloc) IMalloc_AddRef(imalloc); -- 2.10.1 From damjan.jov at gmail.com Sun Oct 30 04:29:19 2016 From: damjan.jov at gmail.com (Damjan Jovanovic) Date: Sun, 30 Oct 2016 11:29:19 +0200 Subject: [PATCH] winex11.drv: import X11's "text/html" as "HTML Format" Message-ID: Initial support for importing "text/html" into Windows's "HTML Format", which fixes pasting rich text into a large number of apps and closes #7372. Currently OpenOffice (SVN trunk), Excel and Firefox work, but apps needing full HTML documents instead of only HTML fragments will only be able to paste from apps that provide those. Signed-off-by: Damjan Jovanovic --- dlls/winex11.drv/clipboard.c | 65 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-winex11.drv-import-X11-s-text-html-as-HTML-Format.txt Type: text/x-patch Size: 4122 bytes Desc: not available URL: From stefandoesinger at gmx.at Sun Oct 30 09:02:25 2016 From: stefandoesinger at gmx.at (=?UTF-8?q?Stefan=20D=C3=B6singer?=) Date: Sun, 30 Oct 2016 07:02:25 -0700 Subject: [PATCH 5/7] ddraw: Discard the dst vertex buffer if possible. In-Reply-To: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> References: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> Message-ID: <1477836147-29984-5-git-send-email-stefandoesinger@gmx.at> Signed-off-by: Stefan Dösinger --- Once we have buffer->buffer copies working we can load the source data into a buffer in SetExecuteData and never have to lock the destination buffer. We could even consider putting the entire execute buffer data in a sysmem wined3d buffer and avoid a memcpy - but that would mean that ddraw accesses the wined3d buffer while it is not locked. --- dlls/ddraw/ddraw_private.h | 1 + dlls/ddraw/executebuffer.c | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 08ab8a2..3f07300 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -528,6 +528,7 @@ struct d3d_execute_buffer unsigned int index_size, index_pos; unsigned int vertex_size, src_vertex_pos; struct wined3d_buffer *src_vertex_buffer, *dst_vertex_buffer, *index_buffer; + DWORD dst_vertex_map_flags; /* This flags is set to TRUE if we allocated ourselves the * data buffer diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index da4d6dc..9cdcdf2 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -327,7 +327,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, box.left = ci->wDest * sizeof(*src); box.right = (ci->wDest + ci->dwCount) * sizeof(*src); hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0, - &map_desc, &box, 0); + &map_desc, &box, buffer->dst_vertex_map_flags); if (FAILED(hr)) return hr; @@ -342,6 +342,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, } instr += size; + buffer->dst_vertex_map_flags = 0; } break; @@ -591,8 +592,8 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer * return hr; hr = wined3d_buffer_create_vb(buffer->d3ddev->wined3d_device, new_size * sizeof(D3DTLVERTEX), - WINED3DUSAGE_STATICDECL, WINED3D_POOL_DEFAULT, - NULL, &ddraw_null_wined3d_parent_ops, &dst_buffer); + WINED3DUSAGE_STATICDECL | WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, + WINED3D_POOL_DEFAULT, NULL, &ddraw_null_wined3d_parent_ops, &dst_buffer); if (FAILED(hr)) { wined3d_buffer_decref(src_buffer); @@ -608,6 +609,7 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer * buffer->dst_vertex_buffer = dst_buffer; buffer->vertex_size = new_size; buffer->src_vertex_pos = 0; + buffer->dst_vertex_map_flags = WINED3D_MAP_DISCARD; } if (TRACE_ON(ddraw)) -- 2.7.3 From stefandoesinger at gmx.at Sun Oct 30 09:02:21 2016 From: stefandoesinger at gmx.at (=?UTF-8?q?Stefan=20D=C3=B6singer?=) Date: Sun, 30 Oct 2016 07:02:21 -0700 Subject: [PATCH 1/7] ddraw: Use d3d buffers for executebuffer data. Message-ID: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> Signed-off-by: Stefan Dösinger --- dlls/ddraw/ddraw_private.h | 5 +- dlls/ddraw/executebuffer.c | 128 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 102 insertions(+), 31 deletions(-) diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 7c2f026..5a25a93 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -525,8 +525,9 @@ struct d3d_execute_buffer /* This buffer will store the transformed vertices */ void *vertex_data; WORD *indices; - unsigned int nb_indices; - unsigned int nb_vertices; + unsigned int index_size; + unsigned int vertex_size; + struct wined3d_buffer *dst_vertex_buffer, *index_buffer; /* This flags is set to TRUE if we allocated ourselves the * data buffer diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index 3becf58..5c53f2b 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -70,6 +70,9 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, DWORD is = buffer->data.dwInstructionOffset; char *instr = (char *)buffer->desc.lpData + is; unsigned int i; + struct wined3d_map_desc map_desc; + struct wined3d_box box = {0}; + HRESULT hr; if (viewport->active_device != device) { @@ -108,21 +111,42 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, case D3DOP_TRIANGLE: { - D3DTLVERTEX *tl_vx = buffer->vertex_data; - TRACE("TRIANGLE (%d)\n", count); + WORD *indices; + TRACE("TRIANGLE (%d)\n", count); - if (buffer->nb_indices < count * 3) + if (!count) + break; + + if (buffer->index_size < count * 3) { - buffer->nb_indices = count * 3; - HeapFree(GetProcessHeap(), 0, buffer->indices); - buffer->indices = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->indices) * buffer->nb_indices); + struct wined3d_buffer *new_buffer; + unsigned int new_size = max(buffer->index_size * 2, count * 3); + + hr = wined3d_buffer_create_ib(device->wined3d_device, new_size * sizeof(*indices), + WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, WINED3D_POOL_DEFAULT, + NULL, &ddraw_null_wined3d_parent_ops, &new_buffer); + if (FAILED(hr)) + return hr; + + buffer->index_size = new_size; + if (buffer->index_buffer) + wined3d_buffer_decref(buffer->index_buffer); + buffer->index_buffer = new_buffer; } + box.left = 0; + box.right = count * 3 * sizeof(*indices); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->index_buffer), 0, + &map_desc, &box, WINED3D_MAP_DISCARD); + if (FAILED(hr)) + return hr; + indices = map_desc.data; + for (i = 0; i < count; ++i) { D3DTRIANGLE *ci = (D3DTRIANGLE *)instr; - TRACE(" v1: %d v2: %d v3: %d\n",ci->u1.v1, ci->u2.v2, ci->u3.v3); - TRACE(" Flags : "); + TRACE(" v1: %d v2: %d v3: %d\n",ci->u1.v1, ci->u2.v2, ci->u3.v3); + TRACE(" Flags : "); if (TRACE_ON(ddraw)) { /* Wireframe */ @@ -143,14 +167,21 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, TRACE("STARTFLAT(%u) ", ci->wFlags); TRACE("\n"); } - buffer->indices[(i * 3) ] = ci->u1.v1; - buffer->indices[(i * 3) + 1] = ci->u2.v2; - buffer->indices[(i * 3) + 2] = ci->u3.v3; + indices[(i * 3) ] = ci->u1.v1; + indices[(i * 3) + 1] = ci->u2.v2; + indices[(i * 3) + 2] = ci->u3.v3; instr += size; } - IDirect3DDevice7_DrawIndexedPrimitive(&device->IDirect3DDevice7_iface, - D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX, tl_vx, buffer->nb_vertices, - buffer->indices, count * 3, 0); + + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->index_buffer), 0); + + wined3d_device_set_stream_source(device->wined3d_device, 0, + buffer->dst_vertex_buffer, 0, sizeof(D3DTLVERTEX)); + wined3d_device_set_vertex_declaration(device->wined3d_device, + ddraw_find_decl(device->ddraw, D3DFVF_TLVERTEX)); + wined3d_device_set_index_buffer(device->wined3d_device, buffer->index_buffer, WINED3DFMT_R16_UINT, 0); + wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_TRIANGLELIST); + wined3d_device_draw_indexed_primitive(device->wined3d_device, 0, count * 3); } break; case D3DOP_MATRIXLOAD: @@ -273,8 +304,8 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, for (i = 0; i < count; ++i) { D3DPROCESSVERTICES *ci = (D3DPROCESSVERTICES *)instr; - D3DTLVERTEX *dst = (D3DTLVERTEX *)buffer->vertex_data + ci->wDest; DWORD op = ci->dwFlags & D3DPROCESSVERTICES_OPMASK; + D3DTLVERTEX *src, *dst; TRACE(" start %u, dest %u, count %u, flags %#x.\n", ci->wStart, ci->wDest, ci->dwCount, ci->dwFlags); @@ -295,6 +326,14 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, if (!once++) FIXME("Lighting not implemented.\n"); + box.left = ci->wDest * sizeof(*dst); + box.right = (ci->wDest + ci->dwCount) * sizeof(*dst); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0, + &map_desc, &box, 0); + if (FAILED(hr)) + return hr; + dst = map_desc.data; + for (vtx_idx = 0; vtx_idx < ci->dwCount; ++vtx_idx) { transform_vertex(&dst[vtx_idx], &mat, &viewport->viewports.vp1, @@ -305,6 +344,9 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, dst[vtx_idx].u7.tu = src[vtx_idx].u7.tu; dst[vtx_idx].u8.tv = src[vtx_idx].u8.tv; } + + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0); + break; } @@ -313,6 +355,14 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, const D3DLVERTEX *src = (D3DLVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart; unsigned int vtx_idx; + box.left = ci->wDest * sizeof(*dst); + box.right = (ci->wDest + ci->dwCount) * sizeof(*dst); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0, + &map_desc, &box, 0); + if (FAILED(hr)) + return hr; + dst = map_desc.data; + for (vtx_idx = 0; vtx_idx < ci->dwCount; ++vtx_idx) { transform_vertex(&dst[vtx_idx], &mat, &viewport->viewports.vp1, @@ -322,16 +372,25 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, dst[vtx_idx].u7.tu = src[vtx_idx].u6.tu; dst[vtx_idx].u8.tv = src[vtx_idx].u7.tv; } + + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0); + break; } case D3DPROCESSVERTICES_COPY: - { - const D3DTLVERTEX *src = (D3DTLVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart; + box.left = ci->wDest * sizeof(*src); + box.right = (ci->wDest + ci->dwCount) * sizeof(*src); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0, + &map_desc, &box, 0); + if (FAILED(hr)) + return hr; + + src = (D3DTLVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart; + memcpy(map_desc.data, src, ci->dwCount * sizeof(*src)); - memcpy(dst, src, ci->dwCount * sizeof(*dst)); + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0); break; - } default: FIXME("Unhandled vertex processing op %#x.\n", op); @@ -476,8 +535,10 @@ static ULONG WINAPI d3d_execute_buffer_Release(IDirect3DExecuteBuffer *iface) { if (buffer->need_free) HeapFree(GetProcessHeap(), 0, buffer->desc.lpData); - HeapFree(GetProcessHeap(), 0, buffer->vertex_data); - HeapFree(GetProcessHeap(), 0, buffer->indices); + if (buffer->index_buffer) + wined3d_buffer_decref(buffer->index_buffer); + if (buffer->dst_vertex_buffer) + wined3d_buffer_decref(buffer->dst_vertex_buffer); HeapFree(GetProcessHeap(), 0, buffer); } @@ -566,19 +627,28 @@ static HRESULT WINAPI d3d_execute_buffer_Unlock(IDirect3DExecuteBuffer *iface) static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer *iface, D3DEXECUTEDATA *data) { struct d3d_execute_buffer *buffer = impl_from_IDirect3DExecuteBuffer(iface); - DWORD nbvert; TRACE("iface %p, data %p.\n", iface, data); memcpy(&buffer->data, data, data->dwSize); - /* Get the number of vertices in the execute buffer */ - nbvert = buffer->data.dwVertexCount; - - /* Prepares the transformed vertex buffer */ - HeapFree(GetProcessHeap(), 0, buffer->vertex_data); - buffer->vertex_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbvert * sizeof(D3DTLVERTEX)); - buffer->nb_vertices = nbvert; + if (buffer->vertex_size < data->dwVertexCount) + { + HRESULT hr; + unsigned int new_size = max(data->dwVertexCount, buffer->vertex_size * 2); + struct wined3d_buffer *dst_buffer; + + hr = wined3d_buffer_create_vb(buffer->d3ddev->wined3d_device, new_size * sizeof(D3DTLVERTEX), + WINED3DUSAGE_STATICDECL, WINED3D_POOL_DEFAULT, + NULL, &ddraw_null_wined3d_parent_ops, &dst_buffer); + if (FAILED(hr)) + return hr; + + if (buffer->dst_vertex_buffer) + wined3d_buffer_decref(buffer->dst_vertex_buffer); + buffer->dst_vertex_buffer = dst_buffer; + buffer->vertex_size = new_size; + } if (TRACE_ON(ddraw)) _dump_executedata(data); -- 2.7.3 From stefandoesinger at gmx.at Sun Oct 30 09:02:26 2016 From: stefandoesinger at gmx.at (=?UTF-8?q?Stefan=20D=C3=B6singer?=) Date: Sun, 30 Oct 2016 07:02:26 -0700 Subject: [PATCH 6/7] ddraw: Implement executebuffer point and line draws. In-Reply-To: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> References: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> Message-ID: <1477836147-29984-6-git-send-email-stefandoesinger@gmx.at> Signed-off-by: Stefan Dösinger --- dlls/ddraw/executebuffer.c | 70 +++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index 9cdcdf2..f0c2b03 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -54,7 +54,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, DWORD vs = buffer->data.dwVertexOffset; DWORD is = buffer->data.dwInstructionOffset; char *instr = (char *)buffer->desc.lpData + is; - unsigned int i; + unsigned int i, primitive_size; struct wined3d_map_desc map_desc; struct wined3d_box box = {0}; HRESULT hr; @@ -82,31 +82,51 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, count = current->wCount; size = current->bSize; instr += sizeof(D3DINSTRUCTION); - - switch (current->bOpcode) { - case D3DOP_POINT: { - WARN("POINT-s (%d)\n", count); - instr += count * size; - } break; + primitive_size = 0; - case D3DOP_LINE: { - WARN("LINE-s (%d)\n", count); - instr += count * size; - } break; + switch (current->bOpcode) + { + case D3DOP_POINT: + { + const D3DPOINT *p = (D3DPOINT *)instr; + wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_POINTLIST); + wined3d_device_set_stream_source(device->wined3d_device, 0, + buffer->dst_vertex_buffer, 0, sizeof(D3DTLVERTEX)); + wined3d_device_set_vertex_declaration(device->wined3d_device, + ddraw_find_decl(device->ddraw, D3DFVF_TLVERTEX)); + for (i = 0; i < count; ++i) + wined3d_device_draw_primitive(device->wined3d_device, p[i].wFirst, p[i].wCount); + + instr += sizeof(*p) * count; + break; + } + + case D3DOP_LINE: + primitive_size = 2; + wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_LINELIST); + /* Drop through. */ case D3DOP_TRIANGLE: { WORD *indices; - unsigned int index_pos = buffer->index_pos; + unsigned int index_pos = buffer->index_pos, num_indices; TRACE("TRIANGLE (%d)\n", count); if (!count) break; - if (buffer->index_size < count * 3) + if (!primitive_size) + { + wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_TRIANGLELIST); + primitive_size = 3; + } + + num_indices = count * primitive_size; + + if (buffer->index_size < num_indices) { struct wined3d_buffer *new_buffer; - unsigned int new_size = max(buffer->index_size * 2, count * 3); + unsigned int new_size = max(buffer->index_size * 2, num_indices); hr = wined3d_buffer_create_ib(device->wined3d_device, new_size * sizeof(*indices), WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, WINED3D_POOL_DEFAULT, @@ -120,13 +140,13 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, buffer->index_buffer = new_buffer; index_pos = 0; } - else if (buffer->index_size - count * 3 < index_pos) + else if (buffer->index_size - num_indices < index_pos) { index_pos = 0; } box.left = index_pos * sizeof(*indices); - box.right = (index_pos + count * 3) * sizeof(*indices); + box.right = (index_pos + num_indices) * sizeof(*indices); hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->index_buffer), 0, &map_desc, &box, index_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); if (FAILED(hr)) @@ -158,9 +178,16 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, TRACE("STARTFLAT(%u) ", ci->wFlags); TRACE("\n"); } - indices[(i * 3) ] = ci->u1.v1; - indices[(i * 3) + 1] = ci->u2.v2; - indices[(i * 3) + 2] = ci->u3.v3; + + switch (primitive_size) + { + case 3: + indices[(i * primitive_size) + 2] = ci->u3.v3; + /* Drop through. */ + case 2: + indices[(i * primitive_size) + 1] = ci->u2.v2; + indices[(i * primitive_size) ] = ci->u1.v1; + } instr += size; } @@ -171,10 +198,9 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, wined3d_device_set_vertex_declaration(device->wined3d_device, ddraw_find_decl(device->ddraw, D3DFVF_TLVERTEX)); wined3d_device_set_index_buffer(device->wined3d_device, buffer->index_buffer, WINED3DFMT_R16_UINT, 0); - wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_TRIANGLELIST); - wined3d_device_draw_indexed_primitive(device->wined3d_device, index_pos, count * 3); + wined3d_device_draw_indexed_primitive(device->wined3d_device, index_pos, num_indices); - buffer->index_pos = index_pos + count * 3; + buffer->index_pos = index_pos + num_indices; break; } -- 2.7.3 From stefandoesinger at gmx.at Sun Oct 30 09:02:23 2016 From: stefandoesinger at gmx.at (=?UTF-8?q?Stefan=20D=C3=B6singer?=) Date: Sun, 30 Oct 2016 07:02:23 -0700 Subject: [PATCH 3/7] ddraw: Avoid redundant index buffer discards. In-Reply-To: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> References: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> Message-ID: <1477836147-29984-3-git-send-email-stefandoesinger@gmx.at> Signed-off-by: Stefan Dösinger --- dlls/ddraw/ddraw_private.h | 2 +- dlls/ddraw/executebuffer.c | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 9cf8d6c..e850ed1 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -525,7 +525,7 @@ struct d3d_execute_buffer /* This buffer will store the transformed vertices */ void *vertex_data; WORD *indices; - unsigned int index_size; + unsigned int index_size, index_pos; unsigned int vertex_size; struct wined3d_buffer *src_vertex_buffer, *dst_vertex_buffer, *index_buffer; diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index 1fc1f28..c1192c0 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -97,6 +97,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, case D3DOP_TRIANGLE: { WORD *indices; + unsigned int index_pos = buffer->index_pos; TRACE("TRIANGLE (%d)\n", count); if (!count) @@ -117,12 +118,17 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, if (buffer->index_buffer) wined3d_buffer_decref(buffer->index_buffer); buffer->index_buffer = new_buffer; + index_pos = 0; + } + else if (buffer->index_size - count * 3 < index_pos) + { + index_pos = 0; } - box.left = 0; - box.right = count * 3 * sizeof(*indices); + box.left = index_pos * sizeof(*indices); + box.right = (index_pos + count * 3) * sizeof(*indices); hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->index_buffer), 0, - &map_desc, &box, WINED3D_MAP_DISCARD); + &map_desc, &box, index_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); if (FAILED(hr)) return hr; indices = map_desc.data; @@ -166,8 +172,11 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, ddraw_find_decl(device->ddraw, D3DFVF_TLVERTEX)); wined3d_device_set_index_buffer(device->wined3d_device, buffer->index_buffer, WINED3DFMT_R16_UINT, 0); wined3d_device_set_primitive_type(device->wined3d_device, WINED3D_PT_TRIANGLELIST); - wined3d_device_draw_indexed_primitive(device->wined3d_device, 0, count * 3); - } break; + wined3d_device_draw_indexed_primitive(device->wined3d_device, index_pos, count * 3); + + buffer->index_pos = index_pos + count * 3; + break; + } case D3DOP_MATRIXLOAD: WARN("MATRIXLOAD-s (%d)\n", count); -- 2.7.3 From stefandoesinger at gmx.at Sun Oct 30 09:02:24 2016 From: stefandoesinger at gmx.at (=?UTF-8?q?Stefan=20D=C3=B6singer?=) Date: Sun, 30 Oct 2016 07:02:24 -0700 Subject: [PATCH 4/7] ddraw: Avoid redundant src vertex buffer discards. In-Reply-To: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> References: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> Message-ID: <1477836147-29984-4-git-send-email-stefandoesinger@gmx.at> Signed-off-by: Stefan Dösinger --- dlls/ddraw/ddraw_private.h | 2 +- dlls/ddraw/executebuffer.c | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index e850ed1..08ab8a2 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -526,7 +526,7 @@ struct d3d_execute_buffer void *vertex_data; WORD *indices; unsigned int index_size, index_pos; - unsigned int vertex_size; + unsigned int vertex_size, src_vertex_pos; struct wined3d_buffer *src_vertex_buffer, *dst_vertex_buffer, *index_buffer; /* This flags is set to TRUE if we allocated ourselves the diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index c1192c0..da4d6dc 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -274,6 +274,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, DWORD op = ci->dwFlags & D3DPROCESSVERTICES_OPMASK; /* D3DVERTEX, D3DLVERTEX and D3DTLVERTEX all have a size of 32 bytes. */ const D3DVERTEX *src = (const D3DVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart; + unsigned int vertex_pos = buffer->src_vertex_pos; TRACE(" start %u, dest %u, count %u, flags %#x.\n", ci->wStart, ci->wDest, ci->dwCount, ci->dwFlags); @@ -287,17 +288,20 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, { case D3DPROCESSVERTICES_TRANSFORMLIGHT: case D3DPROCESSVERTICES_TRANSFORM: - box.left = 0; - box.right = ci->dwCount * sizeof(*src); + if (buffer->vertex_size - ci->dwCount < vertex_pos) + vertex_pos = 0; + + box.left = vertex_pos * sizeof(*src); + box.right = (vertex_pos + ci->dwCount) * sizeof(*src); hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0, - &map_desc, &box, WINED3D_MAP_DISCARD); + &map_desc, &box, vertex_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD); if (FAILED(hr)) return hr; memcpy(map_desc.data, src, ci->dwCount * sizeof(*src)); wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0); wined3d_device_set_stream_source(device->wined3d_device, 0, - buffer->src_vertex_buffer, 0, sizeof(*src)); + buffer->src_vertex_buffer, box.left, sizeof(*src)); if (op == D3DPROCESSVERTICES_TRANSFORMLIGHT) { wined3d_device_set_vertex_declaration(device->wined3d_device, @@ -315,6 +319,8 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, wined3d_device_process_vertices(device->wined3d_device, 0, ci->wDest, ci->dwCount, buffer->dst_vertex_buffer, NULL, 0, D3DFVF_TLVERTEX); + + buffer->src_vertex_pos = vertex_pos + ci->dwCount; break; case D3DPROCESSVERTICES_COPY: @@ -601,6 +607,7 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer * buffer->src_vertex_buffer = src_buffer; buffer->dst_vertex_buffer = dst_buffer; buffer->vertex_size = new_size; + buffer->src_vertex_pos = 0; } if (TRACE_ON(ddraw)) -- 2.7.3 From stefandoesinger at gmx.at Sun Oct 30 09:02:22 2016 From: stefandoesinger at gmx.at (=?UTF-8?q?Stefan=20D=C3=B6singer?=) Date: Sun, 30 Oct 2016 07:02:22 -0700 Subject: [PATCH 2/7] ddraw: Use wined3d_device_process_vertices for execute buffers. In-Reply-To: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> References: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> Message-ID: <1477836147-29984-2-git-send-email-stefandoesinger@gmx.at> Signed-off-by: Stefan Dösinger --- dlls/ddraw/ddraw_private.h | 2 +- dlls/ddraw/executebuffer.c | 136 +++++++++++++-------------------------------- 2 files changed, 41 insertions(+), 97 deletions(-) diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 5a25a93..9cf8d6c 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -527,7 +527,7 @@ struct d3d_execute_buffer WORD *indices; unsigned int index_size; unsigned int vertex_size; - struct wined3d_buffer *dst_vertex_buffer, *index_buffer; + struct wined3d_buffer *src_vertex_buffer, *dst_vertex_buffer, *index_buffer; /* This flags is set to TRUE if we allocated ourselves the * data buffer diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index 5c53f2b..1fc1f28 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -48,21 +48,6 @@ static void _dump_D3DEXECUTEBUFFERDESC(const D3DEXECUTEBUFFERDESC *lpDesc) { TRACE("lpData : %p\n", lpDesc->lpData); } -static void transform_vertex(D3DTLVERTEX *dst, const D3DMATRIX *mat, - const D3DVIEWPORT *vp, float x, float y, float z) -{ - dst->u1.sx = (x * mat->_11) + (y * mat->_21) + (z * mat->_31) + mat->_41; - dst->u2.sy = (x * mat->_12) + (y * mat->_22) + (z * mat->_32) + mat->_42; - dst->u3.sz = (x * mat->_13) + (y * mat->_23) + (z * mat->_33) + mat->_43; - dst->u4.rhw = (x * mat->_14) + (y * mat->_24) + (z * mat->_34) + mat->_44; - - dst->u4.rhw = 1.0f / dst->u4.rhw; - - dst->u1.sx = (dst->u1.sx * dst->u4.rhw + 1.0f) * vp->dwWidth * 0.5 + vp->dwX; - dst->u2.sy = (-dst->u2.sy * dst->u4.rhw + 1.0f) * vp->dwHeight * 0.5 + vp->dwY; - dst->u3.sz *= dst->u4.rhw; -} - HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d_device *device, struct d3d_viewport *viewport) { @@ -272,40 +257,14 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, break; case D3DOP_PROCESSVERTICES: - { - /* TODO: Share code with d3d_vertex_buffer7_ProcessVertices() - * and / or wined3d_device_process_vertices(). */ - D3DMATRIX view_mat, world_mat, proj_mat, mat; - TRACE("PROCESSVERTICES (%d)\n", count); - /* Note that the projection set in wined3d has the legacy clip space - * adjustment built in. */ - wined3d_device_get_transform(device->wined3d_device, - D3DTRANSFORMSTATE_VIEW, (struct wined3d_matrix *)&view_mat); - wined3d_device_get_transform(device->wined3d_device, - D3DTRANSFORMSTATE_PROJECTION, (struct wined3d_matrix *)&proj_mat); - wined3d_device_get_transform(device->wined3d_device, - WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix *)&world_mat); - - if (TRACE_ON(ddraw)) - { - TRACE(" Projection Matrix:\n"); - dump_D3DMATRIX(&proj_mat); - TRACE(" View Matrix:\n"); - dump_D3DMATRIX(&view_mat); - TRACE(" World Matrix:\n"); - dump_D3DMATRIX(&world_mat); - } - - multiply_matrix(&mat, &view_mat, &world_mat); - multiply_matrix(&mat, &proj_mat, &mat); - for (i = 0; i < count; ++i) { D3DPROCESSVERTICES *ci = (D3DPROCESSVERTICES *)instr; DWORD op = ci->dwFlags & D3DPROCESSVERTICES_OPMASK; - D3DTLVERTEX *src, *dst; + /* D3DVERTEX, D3DLVERTEX and D3DTLVERTEX all have a size of 32 bytes. */ + const D3DVERTEX *src = (const D3DVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart; TRACE(" start %u, dest %u, count %u, flags %#x.\n", ci->wStart, ci->wDest, ci->dwCount, ci->dwFlags); @@ -318,65 +277,36 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, switch (op) { case D3DPROCESSVERTICES_TRANSFORMLIGHT: - { - const D3DVERTEX *src = (D3DVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart; - unsigned int vtx_idx; - static unsigned int once; - - if (!once++) - FIXME("Lighting not implemented.\n"); - - box.left = ci->wDest * sizeof(*dst); - box.right = (ci->wDest + ci->dwCount) * sizeof(*dst); - hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0, - &map_desc, &box, 0); + case D3DPROCESSVERTICES_TRANSFORM: + box.left = 0; + box.right = ci->dwCount * sizeof(*src); + hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->src_vertex_buffer), 0, + &map_desc, &box, WINED3D_MAP_DISCARD); if (FAILED(hr)) return hr; - dst = map_desc.data; + memcpy(map_desc.data, src, ci->dwCount * sizeof(*src)); + wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0); - for (vtx_idx = 0; vtx_idx < ci->dwCount; ++vtx_idx) + wined3d_device_set_stream_source(device->wined3d_device, 0, + buffer->src_vertex_buffer, 0, sizeof(*src)); + if (op == D3DPROCESSVERTICES_TRANSFORMLIGHT) { - transform_vertex(&dst[vtx_idx], &mat, &viewport->viewports.vp1, - src[vtx_idx].u1.x, src[vtx_idx].u2.y, src[vtx_idx].u3.z); - /* No lighting yet */ - dst[vtx_idx].u5.color = 0xffffffff; /* Opaque white */ - dst[vtx_idx].u6.specular = 0xff000000; /* No specular and no fog factor */ - dst[vtx_idx].u7.tu = src[vtx_idx].u7.tu; - dst[vtx_idx].u8.tv = src[vtx_idx].u8.tv; + wined3d_device_set_vertex_declaration(device->wined3d_device, + ddraw_find_decl(device->ddraw, D3DFVF_VERTEX)); + wined3d_device_set_render_state(device->wined3d_device, + WINED3D_RS_LIGHTING, TRUE); } - - wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0); - - break; - } - - case D3DPROCESSVERTICES_TRANSFORM: - { - const D3DLVERTEX *src = (D3DLVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart; - unsigned int vtx_idx; - - box.left = ci->wDest * sizeof(*dst); - box.right = (ci->wDest + ci->dwCount) * sizeof(*dst); - hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0, - &map_desc, &box, 0); - if (FAILED(hr)) - return hr; - dst = map_desc.data; - - for (vtx_idx = 0; vtx_idx < ci->dwCount; ++vtx_idx) + else { - transform_vertex(&dst[vtx_idx], &mat, &viewport->viewports.vp1, - src[vtx_idx].u1.x, src[vtx_idx].u2.y, src[vtx_idx].u3.z); - dst[vtx_idx].u5.color = src[vtx_idx].u4.color; - dst[vtx_idx].u6.specular = src[vtx_idx].u5.specular; - dst[vtx_idx].u7.tu = src[vtx_idx].u6.tu; - dst[vtx_idx].u8.tv = src[vtx_idx].u7.tv; + wined3d_device_set_vertex_declaration(device->wined3d_device, + ddraw_find_decl(device->ddraw, D3DFVF_LVERTEX)); + wined3d_device_set_render_state(device->wined3d_device, + WINED3D_RS_LIGHTING, FALSE); } - wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0); - + wined3d_device_process_vertices(device->wined3d_device, 0, ci->wDest, + ci->dwCount, buffer->dst_vertex_buffer, NULL, 0, D3DFVF_TLVERTEX); break; - } case D3DPROCESSVERTICES_COPY: box.left = ci->wDest * sizeof(*src); @@ -386,7 +316,6 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, if (FAILED(hr)) return hr; - src = (D3DTLVERTEX *)((char *)buffer->desc.lpData + vs) + ci->wStart; memcpy(map_desc.data, src, ci->dwCount * sizeof(*src)); wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->dst_vertex_buffer), 0); @@ -400,7 +329,6 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, instr += size; } break; - } case D3DOP_TEXTURELOAD: { WARN("TEXTURELOAD-s (%d)\n", count); @@ -538,7 +466,10 @@ static ULONG WINAPI d3d_execute_buffer_Release(IDirect3DExecuteBuffer *iface) if (buffer->index_buffer) wined3d_buffer_decref(buffer->index_buffer); if (buffer->dst_vertex_buffer) + { + wined3d_buffer_decref(buffer->src_vertex_buffer); wined3d_buffer_decref(buffer->dst_vertex_buffer); + } HeapFree(GetProcessHeap(), 0, buffer); } @@ -636,16 +567,29 @@ static HRESULT WINAPI d3d_execute_buffer_SetExecuteData(IDirect3DExecuteBuffer * { HRESULT hr; unsigned int new_size = max(data->dwVertexCount, buffer->vertex_size * 2); - struct wined3d_buffer *dst_buffer; + struct wined3d_buffer *src_buffer, *dst_buffer; + + hr = wined3d_buffer_create_vb(buffer->d3ddev->wined3d_device, new_size * sizeof(D3DVERTEX), + WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY, WINED3D_POOL_SYSTEM_MEM, + NULL, &ddraw_null_wined3d_parent_ops, &src_buffer); + if (FAILED(hr)) + return hr; hr = wined3d_buffer_create_vb(buffer->d3ddev->wined3d_device, new_size * sizeof(D3DTLVERTEX), WINED3DUSAGE_STATICDECL, WINED3D_POOL_DEFAULT, NULL, &ddraw_null_wined3d_parent_ops, &dst_buffer); if (FAILED(hr)) + { + wined3d_buffer_decref(src_buffer); return hr; + } if (buffer->dst_vertex_buffer) + { + wined3d_buffer_decref(buffer->src_vertex_buffer); wined3d_buffer_decref(buffer->dst_vertex_buffer); + } + buffer->src_vertex_buffer = src_buffer; buffer->dst_vertex_buffer = dst_buffer; buffer->vertex_size = new_size; } -- 2.7.3 From stefandoesinger at gmx.at Sun Oct 30 09:02:27 2016 From: stefandoesinger at gmx.at (=?UTF-8?q?Stefan=20D=C3=B6singer?=) Date: Sun, 30 Oct 2016 07:02:27 -0700 Subject: [PATCH 7/7] ddraw: Fix remaining style issues in executebuffer.c In-Reply-To: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> References: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> Message-ID: <1477836147-29984-7-git-send-email-stefandoesinger@gmx.at> Signed-off-by: Stefan Dösinger --- Feel free to ignore this. With this the file follows the wined3d style, unless I missed something... --- dlls/ddraw/executebuffer.c | 89 ++++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index f0c2b03..4eff806 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -33,14 +33,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw); * *****************************************************************************/ -static void _dump_executedata(const D3DEXECUTEDATA *lpData) { +static void _dump_executedata(const D3DEXECUTEDATA *lpData) +{ TRACE("dwSize : %d\n", lpData->dwSize); TRACE("Vertex Offset : %d Count : %d\n", lpData->dwVertexOffset, lpData->dwVertexCount); TRACE("Instruction Offset : %d Length : %d\n", lpData->dwInstructionOffset, lpData->dwInstructionLength); TRACE("HVertex Offset : %d\n", lpData->dwHVertexOffset); } -static void _dump_D3DEXECUTEBUFFERDESC(const D3DEXECUTEBUFFERDESC *lpDesc) { +static void _dump_D3DEXECUTEBUFFERDESC(const D3DEXECUTEBUFFERDESC *lpDesc) +{ TRACE("dwSize : %d\n", lpDesc->dwSize); TRACE("dwFlags : %x\n", lpDesc->dwFlags); TRACE("dwCaps : %x\n", lpDesc->dwCaps); @@ -76,12 +78,12 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, for (;;) { D3DINSTRUCTION *current = (D3DINSTRUCTION *)instr; - BYTE size; - WORD count; - - count = current->wCount; - size = current->bSize; - instr += sizeof(D3DINSTRUCTION); + BYTE size; + WORD count; + + count = current->wCount; + size = current->bSize; + instr += sizeof(D3DINSTRUCTION); primitive_size = 0; switch (current->bOpcode) @@ -204,10 +206,10 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, break; } - case D3DOP_MATRIXLOAD: - WARN("MATRIXLOAD-s (%d)\n", count); - instr += count * size; - break; + case D3DOP_MATRIXLOAD: + WARN("MATRIXLOAD-s (%d)\n", count); + instr += count * size; + break; case D3DOP_MATRIXMULTIPLY: TRACE("MATRIXMULTIPLY (%d)\n", count); @@ -372,19 +374,16 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, } break; - case D3DOP_TEXTURELOAD: { - WARN("TEXTURELOAD-s (%d)\n", count); - - instr += count * size; - } break; + case D3DOP_TEXTURELOAD: + WARN("TEXTURELOAD-s (%d)\n", count); + instr += count * size; - case D3DOP_EXIT: { - TRACE("EXIT (%d)\n", count); - /* We did this instruction */ - instr += size; - /* Exit this loop */ - goto end_of_buffer; - } break; + case D3DOP_EXIT: + TRACE("EXIT (%d)\n", count); + /* We did this instruction */ + instr += size; + /* Exit this loop */ + goto end_of_buffer; case D3DOP_BRANCHFORWARD: TRACE("BRANCHFORWARD (%d)\n", count); @@ -397,30 +396,34 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, if (!ci->bNegate) { TRACE(" Branch to %d\n", ci->dwOffset); - if (ci->dwOffset) { + if (ci->dwOffset) + { instr = (char*)current + ci->dwOffset; break; } - } - } else { - if (ci->bNegate) { + } + } + else + { + if (ci->bNegate) + { TRACE(" Branch to %d\n", ci->dwOffset); - if (ci->dwOffset) { + if (ci->dwOffset) + { instr = (char*)current + ci->dwOffset; break; } - } - } + } + } - instr += size; + instr += size; } break; - case D3DOP_SPAN: { - WARN("SPAN-s (%d)\n", count); - - instr += count * size; - } break; + case D3DOP_SPAN: + WARN("SPAN-s (%d)\n", count); + instr += count * size; + break; case D3DOP_SETSTATUS: TRACE("SETSTATUS (%d)\n", count); @@ -431,12 +434,12 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, } break; - default: - ERR("Unhandled OpCode %d !!!\n",current->bOpcode); - /* Try to save ... */ - instr += count * size; - break; - } + default: + ERR("Unhandled OpCode %d !!!\n",current->bOpcode); + /* Try to save ... */ + instr += count * size; + break; + } } end_of_buffer: -- 2.7.3 From nsivov at codeweavers.com Sun Oct 30 12:01:52 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Sun, 30 Oct 2016 20:01:52 +0300 Subject: [PATCH 1/2] d2d1/tests: DrawTextLayout() ignores effects that are not brushes Message-ID: <20161030170153.5357-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- Docs mention that render target enters error state if drawing effect is ID2D1Resource, but not a brush, turns out it's not true. dlls/d2d1/tests/d2d1.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index b49ed7d..cf24841 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -2637,6 +2637,8 @@ static void test_draw_text_layout(void) DWRITE_TEXT_RANGE range; D2D1_COLOR_F color; ID2D1SolidColorBrush *brush, *brush2; + ID2D1RectangleGeometry *geometry; + D2D1_RECT_F rect; if (!(device = create_device())) { @@ -2702,6 +2704,26 @@ static void test_draw_text_layout(void) todo_wine ok(hr == D2DERR_WRONG_FACTORY, "EndDraw failure expected, hr %#x.\n", hr); + /* Effect is d2d resource, but not a brush. */ + rect.left = rect.top = 0.0f; + rect.right = rect.bottom = 10.0f; + hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry); + ok(SUCCEEDED(hr), "Failed to geometry, hr %#x.\n", hr); + + range.startPosition = 0; + range.length = 4; + hr = IDWriteTextLayout_SetDrawingEffect(text_layout, (IUnknown*)geometry, range); + ok(SUCCEEDED(hr), "Failed to set drawing effect, hr %#x.\n", hr); + ID2D1RectangleGeometry_Release(geometry); + + ID2D1RenderTarget_BeginDraw(rt); + + origin.x = origin.y = 0.0f; + ID2D1RenderTarget_DrawTextLayout(rt, origin, text_layout, (ID2D1Brush*)brush, D2D1_DRAW_TEXT_OPTIONS_NONE); + + hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL); + ok(hr == S_OK, "EndDraw failure expected, hr %#x.\n", hr); + IDWriteTextFormat_Release(text_format); IDWriteTextLayout_Release(text_layout); IDWriteFactory_Release(dwrite_factory); -- 2.10.1 From nsivov at codeweavers.com Sun Oct 30 12:01:53 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Sun, 30 Oct 2016 20:01:53 +0300 Subject: [PATCH 2/2] d2d1/tests: Test creating bitmap target from uninitialized dc target In-Reply-To: <20161030170153.5357-1-nsivov@codeweavers.com> References: <20161030170153.5357-1-nsivov@codeweavers.com> Message-ID: <20161030170153.5357-2-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/d2d1/tests/d2d1.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index cf24841..4409bb8 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -3001,6 +3001,7 @@ static void test_bitmap_target(void) ID2D1HwndRenderTarget *hwnd_rt; ID2D1Bitmap *bitmap, *bitmap2; ID2D1BitmapRenderTarget *rt; + ID2D1DCRenderTarget *dc_rt; D2D1_SIZE_F size, size2; ID2D1Factory *factory; ID3D10Device1 *device; @@ -3132,6 +3133,36 @@ static void test_bitmap_target(void) ok(!refcount, "Target should be released, got %u.\n", refcount); DestroyWindow(hwnd_rt_desc.hwnd); + + /* Compatible target created from a DC target without associated HDC */ + desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + desc.dpiX = 96.0f; + desc.dpiY = 96.0f; + desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &dc_rt); + ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr); + + hr = ID2D1DCRenderTarget_CreateCompatibleRenderTarget(dc_rt, NULL, NULL, NULL, + D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + + pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(rt); +todo_wine + ok(pixel_size.width == 0 && pixel_size.height == 0, "Got wrong size\n"); + + hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap); + ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr); + pixel_size = ID2D1Bitmap_GetPixelSize(bitmap); +todo_wine + ok(pixel_size.width == 0 && pixel_size.height == 0, "Got wrong size\n"); + ID2D1Bitmap_Release(bitmap); + + ID2D1BitmapRenderTarget_Release(rt); + ID2D1DCRenderTarget_Release(dc_rt); + ID2D1Factory_Release(factory); } -- 2.10.1 From lukasz.wojnilowicz at gmail.com Sat Oct 29 00:52:27 2016 From: lukasz.wojnilowicz at gmail.com (=?UTF-8?q?=C5=81ukasz=20Wojni=C5=82owicz?=) Date: Sat, 29 Oct 2016 07:52:27 +0200 Subject: [website] Polish translation for release 1.9.22 Message-ID: <1477720347-3086-1-git-send-email-lukasz.wojnilowicz@gmail.com> --- news/pl/2016102801.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 news/pl/2016102801.xml diff --git a/news/pl/2016102801.xml b/news/pl/2016102801.xml new file mode 100644 index 0000000..594420b --- /dev/null +++ b/news/pl/2016102801.xml @@ -0,0 +1,16 @@ + +Październik 28, 2016 +Wydano Wine 1.9.22 + +

Wydanie rozwojowe Wine 1.9.22 jest już dostępne.

+

Co nowego w tym wydaniu: +

    +
  • Przystosowano obsługę schowka macOS do nowej struktury.
  • +
  • Początkowa implementacja wyświetlania bitmap w Direct2D.
  • +
  • Szersza implementacja UsługSieciowych.
  • +
  • Kilka kroków dalej do implementacji obsługi HID.
  • +
  • Rozmaite poprawki błędów.
  • +
+

Źródło jest już dostępne. +Paczki binarne są w trakcie budowy i ukażą się wkrótce w przeznaczonych dla nich pobieralniach. +

-- 2.7.4 From gerald at pfeifer.com Sun Oct 30 08:55:33 2016 From: gerald at pfeifer.com (Gerald Pfeifer) Date: Sun, 30 Oct 2016 14:55:33 +0100 (CET) Subject: msvcirt: Avoid "array subscript above array bounds" warnings in test_ostrstream and test_strstreambuf. Message-ID: Hi Iván, hi Piotr, I am now seeing msvcirt.c:4211:34: warning: array subscript is above array bounds msvcirt.c:4218:35: warning: array subscript is above array bounds msvcirt.c:2125:33: warning: array subscript is above array bounds msvcirt.c:2132:34: warning: array subscript is above array bounds when using current GCC development snapshots to build Wine. All of the occurrences are of the form ok(ssb1.base.ebuf == buffer + 0x7fffffff || ssb1.base.ebuf == (char*)-1, ~~~~~~~^~~~~~~~~~~~ Since buffer is defined as char[64], the warning is technically correct. One way to avoid that is casting things to size_t, for example, which the patch below does. Gerald Signed-off-by: Gerald Pfeifer --- dlls/msvcirt/tests/msvcirt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c index 2234abf..fb7c852 100644 --- a/dlls/msvcirt/tests/msvcirt.c +++ b/dlls/msvcirt/tests/msvcirt.c @@ -2122,14 +2122,14 @@ static void test_strstreambuf(void) ok(ssb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", ssb1.base.allocated); ok(ssb1.base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", ssb1.base.unbuffered); ok(ssb1.base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, ssb1.base.base); - ok(ssb1.base.ebuf == buffer + 0x7fffffff || ssb1.base.ebuf == (char*)-1, + ok((size_t)ssb1.base.ebuf == (size_t)buffer + 0x7fffffff || ssb1.base.ebuf == (char*)-1, "wrong buffer end, expected %p + 0x7fffffff or -1, got %p\n", buffer, ssb1.base.ebuf); ok(ssb1.base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, ssb1.base.eback); ok(ssb1.base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, ssb1.base.gptr); ok(ssb1.base.egptr == buffer + 20, "wrong get end, expected %p got %p\n", buffer + 20, ssb1.base.egptr); ok(ssb1.base.pbase == buffer + 20, "wrong put base, expected %p got %p\n", buffer + 20, ssb1.base.pbase); ok(ssb1.base.pptr == buffer + 20, "wrong put pointer, expected %p got %p\n", buffer + 20, ssb1.base.pptr); - ok(ssb1.base.epptr == buffer + 0x7fffffff || ssb1.base.epptr == (char*)-1, + ok((size_t)ssb1.base.epptr == (size_t)buffer + 0x7fffffff || ssb1.base.epptr == (char*)-1, "wrong put end, expected %p + 0x7fffffff or -1, got %p\n", buffer, ssb1.base.epptr); ok(ssb1.dynamic == 0, "expected 0, got %d\n", ssb1.dynamic); ok(ssb1.constant == 1, "expected 1, got %d\n", ssb1.constant); @@ -4208,14 +4208,14 @@ static void test_ostrstream(void) ok(pssb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pssb->base.allocated); ok(pssb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pssb->base.unbuffered); ok(pssb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pssb->base.base); - ok(pssb->base.ebuf == buffer + 0x7fffffff || pssb->base.ebuf == (char*) -1, + ok((size_t)pssb->base.ebuf == (size_t)buffer + 0x7fffffff || pssb->base.ebuf == (char*) -1, "wrong buffer end, expected %p + 0x7fffffff or -1, got %p\n", buffer, pssb->base.ebuf); ok(pssb->base.eback == buffer, "wrong get base, expected %p got %p\n", buffer, pssb->base.eback); ok(pssb->base.gptr == buffer, "wrong get pointer, expected %p got %p\n", buffer, pssb->base.gptr); ok(pssb->base.egptr == buffer, "wrong get end, expected %p got %p\n", buffer, pssb->base.egptr); ok(pssb->base.pbase == buffer, "wrong put base, expected %p got %p\n", buffer, pssb->base.pbase); ok(pssb->base.pptr == buffer + 4, "wrong put pointer, expected %p got %p\n", buffer + 4, pssb->base.pptr); - ok(pssb->base.epptr == buffer + 0x7fffffff || pssb->base.epptr == (char*) -1, + ok((size_t)pssb->base.epptr == (size_t)buffer + 0x7fffffff || pssb->base.epptr == (char*) -1, "wrong buffer end, expected %p + 0x7fffffff or -1, got %p\n", buffer, pssb->base.epptr); ok(pssb->base.do_lock == -1, "expected -1 got %d\n", pssb->base.do_lock); call_func1(p_ostrstream_dtor, &os1.base_ios); -- 2.9.2 From crramirez at gmail.com Sun Oct 30 18:44:12 2016 From: crramirez at gmail.com (Carlos Rafael Ramirez) Date: Sun, 30 Oct 2016 18:44:12 -0500 Subject: [[PATCH v2] ] Fixes https://bugs.winehq.org/show_bug.cgi?id=33636 Message-ID: <1477871052-10449-1-git-send-email-crramirez@gmail.com> Changes in version 2 of this patch: It ensures eat all commands in the cmdList if the 'if' condition is not satified. Also it includes tests with the fixes. Tested on Windows 10 and Ubuntu 16.04.1. Signed-off-by: Carlos Rafael Ramirez --- programs/cmd/builtins.c | 3 +++ programs/cmd/tests/test_builtins.cmd | 11 +++++++++++ programs/cmd/tests/test_builtins.cmd.exp | 13 +++++++++++++ 3 files changed, 27 insertions(+) diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 49c366a..a29a502 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1574,6 +1574,9 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd, } } if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand; + } else if (!processThese) { + if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand; + WINE_TRACE("Ignore the next command as well (next = %p)\n", *cmdList); } else { WINE_TRACE("Found end of this IF statement (next = %p)\n", *cmdList); break; diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index eac5dca..38a7700 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -836,6 +836,17 @@ if 1 GEQ "10" (echo 1 GEQ "10") else echo foo if "1" GEQ "10" (echo 1 GEQ "10") else echo foo if '1' GEQ "10" (echo '1' GEQ "10") else echo foo if "10" GEQ "10" (echo "10" GEQ "10") +echo --- unconditional ampersand after if one line +if "0"=="0" echo 1 & echo 2 & echo 3 else echo 4 +echo --- +echo x & if "0"=="1" echo 1 & echo 2 +echo --- +echo x & if "0"=="1" echo 1 & echo 2 & echo 3 +echo --- +echo x & if "0"=="1" (echo 1 & echo 2 & echo 3) +echo --- +echo x & if "0"=="1" echo 1 & echo 2 & echo 3 else echo 4 +echo --- goto :endIfCompOpsSubroutines rem IF subroutines helpers diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 67e75e0..5775977 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -645,6 +645,19 @@ foo foo '1' GEQ "10" "10" GEQ "10" +--- unconditional ampersand after if one line +1 +2 +3 else echo 4 +--- +x +--- +x +--- +x +--- +x +--- ------------ Testing for ------------ --- plain FOR A -- 2.7.4 From leslie_alistair at hotmail.com Mon Oct 31 01:38:13 2016 From: leslie_alistair at hotmail.com (Alistair Leslie-Hughes) Date: Mon, 31 Oct 2016 06:38:13 +0000 Subject: [PATCH] shell32: Add caption to Run dialog. Message-ID: From: Jared Smudde Signed-off-by: Alistair Leslie-Hughes --- dlls/shell32/shell32.rc | 1 + 1 file changed, 1 insertion(+) diff --git a/dlls/shell32/shell32.rc b/dlls/shell32/shell32.rc index bfba962..9ab2a03 100644 --- a/dlls/shell32/shell32.rc +++ b/dlls/shell32/shell32.rc @@ -330,6 +330,7 @@ FONT 10, "MS Shell Dlg" SHELL_RUN_DLG DIALOG 0, 0, 235, 83 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Run" FONT 8, "MS Shell Dlg" { ICON "", IDC_RUNDLG_ICON, 7, 11, 18, 20, WS_VISIBLE -- 1.9.1 From piotr at codeweavers.com Mon Oct 31 04:03:32 2016 From: piotr at codeweavers.com (Piotr Caban) Date: Mon, 31 Oct 2016 10:03:32 +0100 Subject: [v4 PATCH] ucrtbase: Added _sopen_dispatch/_wsopen_dispatch In-Reply-To: <20161029172227.21725-1-nsivov@codeweavers.com> References: <20161029172227.21725-1-nsivov@codeweavers.com> Message-ID: <37ceff2e-0ae9-bcbe-ab6a-6901bb6e3766@codeweavers.com> Signed-off-by: Piotr Caban From jkucia at codeweavers.com Mon Oct 31 06:48:31 2016 From: jkucia at codeweavers.com (=?UTF-8?q?J=C3=B3zef=20Kucia?=) Date: Mon, 31 Oct 2016 12:48:31 +0100 Subject: [PATCH] wined3d: Invalidate INDEXBUFFER device state when bound index buffer is unloaded. Message-ID: <1477914511-15798-1-git-send-email-jkucia@codeweavers.com> Fixes a regression introduced by commit e3a8cd20ced9f33db64a35f60bc8487ae8173e47. Signed-off-by: Józef Kucia --- dlls/wined3d/buffer.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index a81cd64..13953c9 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -665,7 +665,12 @@ static void buffer_unload(struct wined3d_resource *resource) * happens only once per changed vertexbuffer and should occur rather * rarely. */ if (resource->bind_count) + { device_invalidate_state(device, STATE_STREAMSRC); + + if (buffer->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER) + device_invalidate_state(device, STATE_INDEXBUFFER); + } } resource_unload(resource); -- 2.7.3 From hverbeet at codeweavers.com Mon Oct 31 07:44:48 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 31 Oct 2016 13:44:48 +0100 Subject: [PATCH 1/7] ddraw: Use d3d buffers for executebuffer data. In-Reply-To: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> References: <1477836147-29984-1-git-send-email-stefandoesinger@gmx.at> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 31 07:44:50 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 31 Oct 2016 13:44:50 +0100 Subject: [PATCH 1/2] d2d1/tests: DrawTextLayout() ignores effects that are not brushes In-Reply-To: <20161030170153.5357-1-nsivov@codeweavers.com> References: <20161030170153.5357-1-nsivov@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 31 07:44:51 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 31 Oct 2016 13:44:51 +0100 Subject: [PATCH 2/2] d2d1/tests: Test creating bitmap target from uninitialized dc target In-Reply-To: <20161030170153.5357-2-nsivov@codeweavers.com> References: <20161030170153.5357-2-nsivov@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From hverbeet at codeweavers.com Mon Oct 31 07:44:52 2016 From: hverbeet at codeweavers.com (Henri Verbeet) Date: Mon, 31 Oct 2016 13:44:52 +0100 Subject: [PATCH] wined3d: Invalidate INDEXBUFFER device state when bound index buffer is unloaded. In-Reply-To: <1477914511-15798-1-git-send-email-jkucia@codeweavers.com> References: <1477914511-15798-1-git-send-email-jkucia@codeweavers.com> Message-ID: Signed-off-by: Henri Verbeet From crramirez at gmail.com Mon Oct 31 18:57:33 2016 From: crramirez at gmail.com (Carlos Rafael Ramirez) Date: Mon, 31 Oct 2016 18:57:33 -0500 Subject: [PATCH v3] cmd: if 'if' condition is not met and cmdList->nextCommand is not null, all commands in the list should be ignored as well Message-ID: <1477958253-2268-1-git-send-email-crramirez@gmail.com> Fixes https://bugs.winehq.org/show_bug.cgi?id=33636 Changes in version 3 of this patch: Correct the subject Changes in version 2 of this patch: It ensures eat all commands in the cmdList if the 'if' condition is not satified. Also it includes tests with the fixes. Tested on Windows 10 and Ubuntu 16.04.1. Signed-off-by: Carlos Rafael Ramirez --- programs/cmd/builtins.c | 3 +++ programs/cmd/tests/test_builtins.cmd | 11 +++++++++++ programs/cmd/tests/test_builtins.cmd.exp | 13 +++++++++++++ 3 files changed, 27 insertions(+) diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 49c366a..a29a502 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1574,6 +1574,9 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd, } } if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand; + } else if (!processThese) { + if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand; + WINE_TRACE("Ignore the next command as well (next = %p)\n", *cmdList); } else { WINE_TRACE("Found end of this IF statement (next = %p)\n", *cmdList); break; diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index eac5dca..38a7700 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -836,6 +836,17 @@ if 1 GEQ "10" (echo 1 GEQ "10") else echo foo if "1" GEQ "10" (echo 1 GEQ "10") else echo foo if '1' GEQ "10" (echo '1' GEQ "10") else echo foo if "10" GEQ "10" (echo "10" GEQ "10") +echo --- unconditional ampersand after if one line +if "0"=="0" echo 1 & echo 2 & echo 3 else echo 4 +echo --- +echo x & if "0"=="1" echo 1 & echo 2 +echo --- +echo x & if "0"=="1" echo 1 & echo 2 & echo 3 +echo --- +echo x & if "0"=="1" (echo 1 & echo 2 & echo 3) +echo --- +echo x & if "0"=="1" echo 1 & echo 2 & echo 3 else echo 4 +echo --- goto :endIfCompOpsSubroutines rem IF subroutines helpers diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 67e75e0..5775977 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -645,6 +645,19 @@ foo foo '1' GEQ "10" "10" GEQ "10" +--- unconditional ampersand after if one line +1 +2 +3 else echo 4 +--- +x +--- +x +--- +x +--- +x +--- ------------ Testing for ------------ --- plain FOR A -- 2.7.4 From andrey.goosev at gmail.com Mon Oct 31 19:01:38 2016 From: andrey.goosev at gmail.com (Andrey Gusev) Date: Tue, 1 Nov 2016 02:01:38 +0200 Subject: wined3d: Add ARB_texture_env_crossbar extension. Message-ID: -------------- next part -------------- A non-text attachment was scrubbed... Name: wined3d-Add-ARB_texture_env_crossbar-extension.patch Type: text/x-patch Size: 1675 bytes Desc: not available URL: From nsivov at codeweavers.com Mon Oct 31 19:33:28 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Tue, 1 Nov 2016 03:33:28 +0300 Subject: [PATCH] gdiplus: Implement GdipBitmapGetHistogramSize Message-ID: <20161101003328.26785-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/gdiplus/gdiplus.spec | 2 +- dlls/gdiplus/image.c | 14 +++++++++++++ dlls/gdiplus/tests/image.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ include/gdipluscolormatrix.h | 13 ++++++++++++ include/gdiplusflat.h | 1 + 5 files changed, 77 insertions(+), 1 deletion(-) diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec index db0a49a..92251a7 100644 --- a/dlls/gdiplus/gdiplus.spec +++ b/dlls/gdiplus/gdiplus.spec @@ -619,7 +619,7 @@ 619 stdcall GdipBitmapCreateApplyEffect(ptr long ptr ptr ptr ptr long ptr ptr) 620 stdcall GdipBitmapApplyEffect(ptr ptr ptr long ptr ptr) 621 stub GdipBitmapGetHistogram -622 stub GdipBitmapGetHistogramSize +622 stdcall GdipBitmapGetHistogramSize(long ptr) 623 stdcall GdipBitmapConvertFormat(ptr long long long ptr float) 624 stdcall GdipImageSetAbort(ptr ptr) 625 stub GdipGraphicsSetAbort diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index 74fad29..672b2e5 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -5386,3 +5386,17 @@ GpStatus WINGDIPAPI GdipBitmapConvertFormat(GpBitmap *bitmap, PixelFormat format FIXME("(%p, 0x%08x, %d, %d, %p, %f): stub\n", bitmap, format, dithertype, palettetype, palette, alphathreshold); return NotImplemented; } + +/***************************************************************************** + * GdipBitmapGetHistogramSize [GDIPLUS.@] + */ +GpStatus WINGDIPAPI GdipBitmapGetHistogramSize(HistogramFormat format, UINT *num_of_entries) +{ + TRACE("(%d, %p)\n", format, num_of_entries); + + if (!num_of_entries) + return InvalidParameter; + + *num_of_entries = 256; + return Ok; +} diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index 8c123b9..baf5c3b 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -30,6 +30,8 @@ #include "gdiplus.h" #include "wine/test.h" +static GpStatus (WINAPI *pGdipBitmapGetHistogramSize)(HistogramFormat,UINT*); + #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got)) #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got)) @@ -4785,8 +4787,51 @@ static void test_getadjustedpalette(void) GdipDisposeImageAttributes(imageattributes); } +static void test_histogramsize(void) +{ + HistogramFormat test_formats[] = + { + HistogramFormatARGB, + HistogramFormatPARGB, + HistogramFormatRGB, + HistogramFormatGray, + HistogramFormatB, + HistogramFormatG, + HistogramFormatR, + HistogramFormatA, + }; + GpStatus stat; + UINT num, i; + + if (!pGdipBitmapGetHistogramSize) + { + win_skip("GdipBitmapGetHistogramSize is not supported\n"); + return; + } + + stat = pGdipBitmapGetHistogramSize(HistogramFormatARGB, NULL); + expect(InvalidParameter, stat); + + stat = pGdipBitmapGetHistogramSize(0xff, NULL); + expect(InvalidParameter, stat); + + num = 123; + stat = pGdipBitmapGetHistogramSize(10, &num); + expect(Ok, stat); + expect(256, num); + + for (i = 0; i < sizeof(test_formats)/sizeof(test_formats[0]); i++) + { + num = 0; + stat = pGdipBitmapGetHistogramSize(test_formats[i], &num); + expect(Ok, stat); + expect(256, num); + } +} + START_TEST(image) { + HMODULE mod = GetModuleHandleA("gdiplus.dll"); struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; @@ -4797,6 +4842,8 @@ START_TEST(image) GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); + pGdipBitmapGetHistogramSize = (void*)GetProcAddress(mod, "GdipBitmapGetHistogramSize"); + test_supported_encoders(); test_CloneBitmapArea(); test_ARGB_conversion(); @@ -4843,6 +4890,7 @@ START_TEST(image) test_dispose(); test_createeffect(); test_getadjustedpalette(); + test_histogramsize(); GdiplusShutdown(gdiplusToken); } diff --git a/include/gdipluscolormatrix.h b/include/gdipluscolormatrix.h index fbf1b2a..44016ff 100644 --- a/include/gdipluscolormatrix.h +++ b/include/gdipluscolormatrix.h @@ -48,10 +48,23 @@ struct ColorMap Color newColor; }; +enum HistogramFormat +{ + HistogramFormatARGB, + HistogramFormatPARGB, + HistogramFormatRGB, + HistogramFormatGray, + HistogramFormatB, + HistogramFormatG, + HistogramFormatR, + HistogramFormatA, +}; + #ifndef __cplusplus typedef enum ColorAdjustType ColorAdjustType; typedef enum ColorMatrixFlags ColorMatrixFlags; +typedef enum HistogramFormat HistogramFormat; typedef struct ColorMatrix ColorMatrix; typedef struct ColorMap ColorMap; diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h index c6f16c4..824b460 100644 --- a/include/gdiplusflat.h +++ b/include/gdiplusflat.h @@ -41,6 +41,7 @@ GpStatus WINGDIPAPI GdipSetAdjustableArrowCapWidth(GpAdjustableArrowCap*,REAL); /* Bitmap */ GpStatus WINGDIPAPI GdipBitmapApplyEffect(GpBitmap*,CGpEffect*,RECT*,BOOL,VOID**,INT*); GpStatus WINGDIPAPI GdipBitmapCreateApplyEffect(GpBitmap**,INT,CGpEffect*,RECT*,RECT*,GpBitmap**,BOOL,VOID**,INT*); +GpStatus WINGDIPAPI GdipBitmapGetHistogramSize(HistogramFormat,UINT*); GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap*,INT,INT,ARGB*); GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap*,GDIPCONST GpRect*,UINT, PixelFormat,BitmapData*); -- 2.10.1 From nsivov at codeweavers.com Mon Oct 31 19:34:04 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Tue, 1 Nov 2016 03:34:04 +0300 Subject: [PATCH 1/2] d2d1: For transformed geometry forward StrokeContainsPoint() to its source geometry Message-ID: <20161101003405.26921-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/d2d1/geometry.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c index 385e171..4abe9bc 100644 --- a/dlls/d2d1/geometry.c +++ b/dlls/d2d1/geometry.c @@ -2633,11 +2633,19 @@ static HRESULT STDMETHODCALLTYPE d2d_transformed_geometry_StrokeContainsPoint(ID D2D1_POINT_2F point, float stroke_width, ID2D1StrokeStyle *stroke_style, const D2D1_MATRIX_3X2_F *transform, float tolerance, BOOL *contains) { - FIXME("iface %p, point {%.8e, %.8e}, stroke_width %.8e, stroke_style %p, " - "transform %p, tolerance %.8e, contains %p stub!\n", + struct d2d_geometry *geometry = impl_from_ID2D1TransformedGeometry(iface); + D2D1_MATRIX_3X2_F g; + + TRACE("iface %p, point {%.8e, %.8e}, stroke_width %.8e, stroke_style %p, " + "transform %p, tolerance %.8e, contains %p.\n", iface, point.x, point.y, stroke_width, stroke_style, transform, tolerance, contains); - return E_NOTIMPL; + g = geometry->transform; + if (transform) + d2d_matrix_multiply(&g, transform); + + return ID2D1Geometry_StrokeContainsPoint(geometry->u.transformed.src_geometry, point, stroke_width, stroke_style, + &g, tolerance, contains); } static HRESULT STDMETHODCALLTYPE d2d_transformed_geometry_FillContainsPoint(ID2D1TransformedGeometry *iface, -- 2.10.1 From nsivov at codeweavers.com Mon Oct 31 19:34:05 2016 From: nsivov at codeweavers.com (Nikolay Sivov) Date: Tue, 1 Nov 2016 03:34:05 +0300 Subject: [PATCH 2/2] d2d1: Fix a typo in traced error message parameter In-Reply-To: <20161101003405.26921-1-nsivov@codeweavers.com> References: <20161101003405.26921-1-nsivov@codeweavers.com> Message-ID: <20161101003405.26921-2-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/d2d1/brush.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c index 4110b48..d51f53f 100644 --- a/dlls/d2d1/brush.c +++ b/dlls/d2d1/brush.c @@ -881,7 +881,7 @@ HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_b { if (opacity_brush->type >= sizeof(brush_sizes) / sizeof(*brush_sizes)) { - ERR("Unhandled opacity brush type %#x.\n", brush->type); + ERR("Unhandled opacity brush type %#x.\n", opacity_brush->type); return E_NOTIMPL; } buffer_desc.ByteWidth += brush_sizes[opacity_brush->type]; -- 2.10.1