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