[PATCH 3/3] ddraw/tests: Port D3D1_ViewportClearTest to ddraw1.c.

Stefan Dösinger stefan at codeweavers.com
Sun Feb 15 13:39:12 CST 2015


This removes the last IDirect3DDevice1 test from visual.c. For ddraw4
and ddraw7 there are D3D3_ViewportClearTest and clear_test that still
have to be moved.
---
 dlls/ddraw/tests/ddraw1.c |  62 ++++++++++
 dlls/ddraw/tests/ddraw2.c |  62 ++++++++++
 dlls/ddraw/tests/visual.c | 291 +---------------------------------------------
 3 files changed, 126 insertions(+), 289 deletions(-)

diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 514baef..db09102 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -6303,6 +6303,67 @@ static void test_texturemapblend(void)
     DestroyWindow(window);
 }
 
+static void test_viewport_clear_rect(void)
+{
+    HRESULT hr;
+    static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
+    static D3DRECT clear_rect2 = {{90}, {90}, {110}, {110}};
+    IDirectDrawSurface *rt;
+    HWND window;
+    IDirectDraw *ddraw;
+    IDirect3DDevice *device;
+    IDirect3DMaterial *red, *green;
+    IDirect3DViewport *viewport, *viewport2;
+    ULONG ref;
+    D3DCOLOR color;
+
+    window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+            0, 0, 640, 480, 0, 0, 0, 0);
+    ddraw = create_ddraw();
+    ok(!!ddraw, "Failed to create a ddraw object.\n");
+    if (!(device = create_device(ddraw, window, DDSCL_NORMAL)))
+    {
+        skip("Failed to create a 3D device, skipping test.\n");
+        DestroyWindow(window);
+        IDirectDraw_Release(ddraw);
+        return;
+    }
+
+    hr = IDirect3DDevice_QueryInterface(device, &IID_IDirectDrawSurface, (void **)&rt);
+    ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
+
+    red = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f);
+    viewport = create_viewport(device, 0, 0, 640, 480);
+    viewport_set_background(device, viewport, red);
+    hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
+    ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+    green = create_diffuse_material(device, 0.0f, 1.0f, 0.0f, 1.0f);
+    viewport2 = create_viewport(device, 100, 100, 200, 200);
+    viewport_set_background(device, viewport2, green);
+    hr = IDirect3DViewport_Clear(viewport2, 1, &clear_rect2, D3DCLEAR_TARGET);
+    ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+    color = get_surface_color(rt, 85, 85);
+    ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
+    color = get_surface_color(rt, 95, 95);
+    ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
+    color = get_surface_color(rt, 105, 105);
+    ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
+    color = get_surface_color(rt, 115, 115);
+    ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
+
+    destroy_viewport(device, viewport2);
+    destroy_material(green);
+    destroy_viewport(device, viewport);
+    destroy_material(red);
+    IDirectDrawSurface_Release(rt);
+    IDirect3DDevice_Release(device);
+    ref = IDirectDraw_Release(ddraw);
+    ok(ref == 0, "Ddraw object not properly released, refcount %u.\n", ref);
+    DestroyWindow(window);
+}
+
 START_TEST(ddraw1)
 {
     IDirectDraw *ddraw;
@@ -6369,4 +6430,5 @@ START_TEST(ddraw1)
     test_lost_device();
     test_surface_desc_lock();
     test_texturemapblend();
+    test_viewport_clear_rect();
 }
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index a81f0a7..8b3619e 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -7329,6 +7329,67 @@ static void test_texturemapblend(void)
     DestroyWindow(window);
 }
 
+static void test_viewport_clear_rect(void)
+{
+    HRESULT hr;
+    static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
+    static D3DRECT clear_rect2 = {{90}, {90}, {110}, {110}};
+    IDirectDrawSurface *rt;
+    HWND window;
+    IDirectDraw2 *ddraw;
+    IDirect3DDevice2 *device;
+    IDirect3DMaterial2 *red, *green;
+    IDirect3DViewport2 *viewport, *viewport2;
+    ULONG ref;
+    D3DCOLOR color;
+
+    window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+            0, 0, 640, 480, 0, 0, 0, 0);
+    ddraw = create_ddraw();
+    ok(!!ddraw, "Failed to create a ddraw object.\n");
+    if (!(device = create_device(ddraw, window, DDSCL_NORMAL)))
+    {
+        skip("Failed to create a 3D device, skipping test.\n");
+        DestroyWindow(window);
+        IDirectDraw2_Release(ddraw);
+        return;
+    }
+
+    hr = IDirect3DDevice2_GetRenderTarget(device, &rt);
+    ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
+
+    red = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f);
+    viewport = create_viewport(device, 0, 0, 640, 480);
+    viewport_set_background(device, viewport, red);
+    hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
+    ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+    green = create_diffuse_material(device, 0.0f, 1.0f, 0.0f, 1.0f);
+    viewport2 = create_viewport(device, 100, 100, 200, 200);
+    viewport_set_background(device, viewport2, green);
+    hr = IDirect3DViewport2_Clear(viewport2, 1, &clear_rect2, D3DCLEAR_TARGET);
+    ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+    color = get_surface_color(rt, 85, 85);
+    ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
+    color = get_surface_color(rt, 95, 95);
+    ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
+    color = get_surface_color(rt, 105, 105);
+    ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
+    color = get_surface_color(rt, 115, 115);
+    ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
+
+    destroy_viewport(device, viewport2);
+    destroy_material(green);
+    destroy_viewport(device, viewport);
+    destroy_material(red);
+    IDirectDrawSurface_Release(rt);
+    IDirect3DDevice2_Release(device);
+    ref = IDirectDraw2_Release(ddraw);
+    ok(ref == 0, "Ddraw object not properly released, refcount %u.\n", ref);
+    DestroyWindow(window);
+}
+
 START_TEST(ddraw2)
 {
     IDirectDraw2 *ddraw;
@@ -7401,4 +7462,5 @@ START_TEST(ddraw2)
     test_lost_device();
     test_surface_desc_lock();
     test_texturemapblend();
+    test_viewport_clear_rect();
 }
diff --git a/dlls/ddraw/tests/visual.c b/dlls/ddraw/tests/visual.c
index 9c7907a..602544f 100644
--- a/dlls/ddraw/tests/visual.c
+++ b/dlls/ddraw/tests/visual.c
@@ -40,13 +40,6 @@ static IDirectDrawSurface7 *depth_buffer;
 static IDirect3D7          *Direct3D;
 static IDirect3DDevice7    *Direct3DDevice;
 
-static IDirectDraw *DirectDraw1;
-static IDirectDrawSurface *Surface1;
-static IDirect3D *Direct3D1;
-static IDirect3DDevice *Direct3DDevice1;
-static IDirect3DExecuteBuffer *ExecuteBuffer;
-static IDirect3DViewport *Viewport;
-
 static BOOL refdevice = FALSE;
 
 static HRESULT (WINAPI *pDirectDrawCreateEx)(GUID *driver_guid,
@@ -1151,281 +1144,6 @@ static void rhw_zero_test(IDirect3DDevice7 *device)
     ok(color == 0, "Got color %08x, expected 00000000\n", color);
 }
 
-static BOOL D3D1_createObjects(void)
-{
-    WNDCLASSA wc = {0};
-    HRESULT hr;
-    DDSURFACEDESC ddsd;
-    D3DEXECUTEBUFFERDESC exdesc;
-    D3DVIEWPORT vp_data;
-
-    /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
-    hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
-
-    ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr);
-    if (FAILED(hr)) {
-        return FALSE;
-    }
-
-    wc.lpfnWndProc = DefWindowProcA;
-    wc.lpszClassName = "texturemapblend_test_wc";
-    RegisterClassA(&wc);
-    window = CreateWindowA("texturemapblend_test_wc", "texturemapblend_test",
-            WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, 640, 480, 0, 0, 0, 0);
-
-    hr = IDirectDraw_SetCooperativeLevel(DirectDraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
-    ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
-    if(FAILED(hr)) {
-        return FALSE;
-    }
-
-    hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 32);
-    if(FAILED(hr)) {
-        /* 24 bit is fine too */
-        hr = IDirectDraw_SetDisplayMode(DirectDraw1, 640, 480, 24);
-    }
-    ok(hr==DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode returned: %x\n", hr);
-    if (FAILED(hr)) {
-        return FALSE;
-    }
-
-    hr = IDirectDraw_QueryInterface(DirectDraw1, &IID_IDirect3D, (void**) &Direct3D1);
-    ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
-    if (FAILED(hr)) {
-        return FALSE;
-    }
-
-    memset(&ddsd, 0, sizeof(ddsd));
-    ddsd.dwSize = sizeof(ddsd);
-    ddsd.dwFlags = DDSD_CAPS;
-    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
-    hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &Surface1, NULL);
-    ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
-    if (FAILED(hr)) {
-        return FALSE;
-    }
-
-    hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **) &Direct3DDevice1);
-    if(FAILED(hr)) {
-        trace("Creating a HAL device failed, trying Ref\n");
-        hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DRefDevice, (void **) &Direct3DDevice1);
-    }
-    ok(hr==D3D_OK, "Creating 3D device returned: %x\n", hr);
-    if(FAILED(hr)) {
-        return FALSE;
-    }
-
-    hr = IDirect3D_CreateViewport(Direct3D1, &Viewport, NULL);
-    ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
-    if (FAILED(hr)) {
-        return FALSE;
-    }
-
-    hr = IDirect3DViewport_Initialize(Viewport, Direct3D1);
-    ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
-    hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport);
-    ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
-    vp_data.dwSize = sizeof(vp_data);
-    vp_data.dwX = 0;
-    vp_data.dwY = 0;
-    vp_data.dwWidth = 640;
-    vp_data.dwHeight = 480;
-    vp_data.dvScaleX = 1;
-    vp_data.dvScaleY = 1;
-    vp_data.dvMaxX = 640;
-    vp_data.dvMaxY = 480;
-    vp_data.dvMinZ = 0;
-    vp_data.dvMaxZ = 1;
-    hr = IDirect3DViewport_SetViewport(Viewport, &vp_data);
-    ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
-
-    memset(&exdesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
-    exdesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
-    exdesc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
-    exdesc.dwBufferSize = 512;
-    exdesc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY;
-    hr = IDirect3DDevice_CreateExecuteBuffer(Direct3DDevice1, &exdesc, &ExecuteBuffer, NULL);
-    ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed with %08x\n", hr);
-    if (FAILED(hr)) {
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-static void D3D1_releaseObjects(void)
-{
-    if(ExecuteBuffer) IDirect3DExecuteBuffer_Release(ExecuteBuffer);
-    if(Surface1) IDirectDrawSurface_Release(Surface1);
-    if(Viewport) IDirect3DViewport_Release(Viewport);
-    if(Direct3DDevice1) IDirect3DDevice_Release(Direct3DDevice1);
-    if(Direct3D1) IDirect3D_Release(Direct3D1);
-    if(DirectDraw1) IDirectDraw_Release(DirectDraw1);
-    if(window) DestroyWindow(window);
-}
-
-static DWORD D3D1_getPixelColor(IDirectDraw *DirectDraw1, IDirectDrawSurface *Surface, UINT x, UINT y)
-{
-    DWORD ret;
-    HRESULT hr;
-    DDSURFACEDESC ddsd;
-    RECT rectToLock = {x, y, x+1, y+1};
-    IDirectDrawSurface *surf = NULL;
-
-    /* Some implementations seem to dislike direct locking on the front buffer. Thus copy the front buffer
-     * to an offscreen surface and lock it instead of the front buffer
-     */
-    memset(&ddsd, 0, sizeof(ddsd));
-    ddsd.dwSize = sizeof(ddsd);
-    ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
-    ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
-    ddsd.dwWidth = 640;
-    ddsd.dwHeight = 480;
-    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
-    hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd, &surf, NULL);
-    ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
-    if(!surf)
-    {
-        trace("cannot create helper surface\n");
-        return 0xdeadbeef;
-    }
-
-    memset(&ddsd, 0, sizeof(ddsd));
-    ddsd.dwSize = sizeof(ddsd);
-    ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
-
-    hr = IDirectDrawSurface_BltFast(surf, 0, 0, Surface, NULL, 0);
-    ok(hr == DD_OK, "IDirectDrawSurface_BltFast returned %08x\n", hr);
-    if(FAILED(hr))
-    {
-        trace("Cannot blit\n");
-        ret = 0xdeadbee;
-        goto out;
-    }
-
-    hr = IDirectDrawSurface_Lock(surf, &rectToLock, &ddsd, DDLOCK_READONLY | DDLOCK_WAIT, NULL);
-    if(FAILED(hr))
-    {
-        trace("Can't lock the offscreen surface, hr=%08x\n", hr);
-        ret = 0xdeadbeec;
-        goto out;
-    }
-
-    /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
-     * really important for these tests
-     */
-    ret = ((DWORD *) ddsd.lpSurface)[0] & 0x00ffffff;
-    hr = IDirectDrawSurface_Unlock(surf, NULL);
-    if(FAILED(hr))
-    {
-        trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
-    }
-
-out:
-    IDirectDrawSurface_Release(surf);
-    return ret;
-}
-
-static void D3D1_ViewportClearTest(void)
-{
-    HRESULT hr;
-    IDirect3DMaterial *bgMaterial = NULL;
-    D3DMATERIAL mat;
-    D3DMATERIALHANDLE hMat;
-    D3DVIEWPORT vp_data;
-    IDirect3DViewport *Viewport2 = NULL;
-    DWORD color, red, green, blue;
-
-    hr = IDirect3D_CreateMaterial(Direct3D1, &bgMaterial, NULL);
-    ok(hr == D3D_OK, "IDirect3D_CreateMaterial failed: %08x\n", hr);
-    if (FAILED(hr)) {
-        goto out;
-    }
-
-    hr = IDirect3D_CreateViewport(Direct3D1, &Viewport2, NULL);
-    ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
-    if (FAILED(hr)) {
-        goto out;
-    }
-
-    hr = IDirect3DViewport_Initialize(Viewport2, Direct3D1);
-    ok(hr == D3D_OK || hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
-    hr = IDirect3DDevice_AddViewport(Direct3DDevice1, Viewport2);
-    ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
-    vp_data.dwSize = sizeof(vp_data);
-    vp_data.dwX = 200;
-    vp_data.dwY = 200;
-    vp_data.dwWidth = 100;
-    vp_data.dwHeight = 100;
-    vp_data.dvScaleX = 1;
-    vp_data.dvScaleY = 1;
-    vp_data.dvMaxX = 100;
-    vp_data.dvMaxY = 100;
-    vp_data.dvMinZ = 0;
-    vp_data.dvMaxZ = 1;
-    hr = IDirect3DViewport_SetViewport(Viewport2, &vp_data);
-    ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
-
-    memset(&mat, 0, sizeof(mat));
-    mat.dwSize = sizeof(mat);
-    U1(U(mat).diffuse).r = 1.0f;
-    hr = IDirect3DMaterial_SetMaterial(bgMaterial, &mat);
-    ok(hr == D3D_OK, "IDirect3DMaterial_SetMaterial failed: %08x\n", hr);
-
-    hr = IDirect3DMaterial_GetHandle(bgMaterial, Direct3DDevice1, &hMat);
-    ok(hr == D3D_OK, "IDirect3DMaterial_GetHandle failed: %08x\n", hr);
-
-    hr = IDirect3DViewport_SetBackground(Viewport, hMat);
-    ok(hr == D3D_OK, "IDirect3DViewport_SetBackground failed: %08x\n", hr);
-    hr = IDirect3DViewport_SetBackground(Viewport2, hMat);
-    ok(hr == D3D_OK, "IDirect3DViewport_SetBackground failed: %08x\n", hr);
-
-    hr = IDirect3DDevice_BeginScene(Direct3DDevice1);
-    ok(hr == D3D_OK, "IDirect3DDevice_BeginScene failed with %08x\n", hr);
-
-    if (SUCCEEDED(hr)) {
-        D3DRECT rect;
-
-        U1(rect).x1 = U2(rect).y1 = 0;
-        U3(rect).x2 = 640;
-        U4(rect).y2 = 480;
-
-        hr = IDirect3DViewport_Clear(Viewport,  1,  &rect, D3DCLEAR_TARGET);
-        ok(hr == D3D_OK, "IDirect3DViewport_Clear failed: %08x\n", hr);
-
-        memset(&mat, 0, sizeof(mat));
-        mat.dwSize = sizeof(mat);
-        U3(U(mat).diffuse).b = 1.0f;
-        hr = IDirect3DMaterial_SetMaterial(bgMaterial, &mat);
-        ok(hr == D3D_OK, "IDirect3DMaterial_SetMaterial failed: %08x\n", hr);
-
-        hr = IDirect3DViewport_Clear(Viewport2,  1,  &rect, D3DCLEAR_TARGET);
-        ok(hr == D3D_OK, "IDirect3DViewport_Clear failed: %08x\n", hr);
-
-        hr = IDirect3DDevice_EndScene(Direct3DDevice1);
-        ok(hr == D3D_OK, "IDirect3DDevice_EndScene failed, hr = %08x\n", hr);
-        }
-
-    color = D3D1_getPixelColor(DirectDraw1, Surface1, 5, 5);
-    red =   (color & 0x00ff0000) >> 16;
-    green = (color & 0x0000ff00) >>  8;
-    blue =  (color & 0x000000ff);
-    ok((red == 0xff && green == 0 && blue == 0) ||
-       broken(red == 0 && green == 0 && blue == 0xff), /* VMware and some native boxes */
-       "Got color %08x, expected 00ff0000\n", color);
-
-    color = D3D1_getPixelColor(DirectDraw1, Surface1, 205, 205);
-    red =   (color & 0x00ff0000) >> 16;
-    green = (color & 0x0000ff00) >>  8;
-    blue =  (color & 0x000000ff);
-    ok(red == 0 && green == 0 && blue == 0xff, "Got color %08x, expected 000000ff\n", color);
-
-    out:
-
-    if (bgMaterial) IDirect3DMaterial_Release(bgMaterial);
-    if (Viewport2) IDirect3DViewport_Release(Viewport2);
-}
-
 static DWORD D3D3_getPixelColor(IDirectDraw4 *DirectDraw, IDirectDrawSurface4 *Surface, UINT x, UINT y)
 {
     DWORD ret;
@@ -1783,6 +1501,8 @@ static void p8_primary_test(void)
     RECT rect;
     DDCOLORKEY clrKey;
     unsigned differences;
+    IDirectDraw *DirectDraw1;
+    IDirectDrawSurface *Surface1;
 
     /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
     hr = DirectDrawCreate(NULL, &DirectDraw1, NULL);
@@ -2545,13 +2265,6 @@ START_TEST(visual)
 
     releaseObjects(); /* release DX7 interfaces to test D3D1 */
 
-    if(!D3D1_createObjects())
-        skip("Cannot initialize D3D1, skipping\n");
-    else
-        D3D1_ViewportClearTest();
-
-    D3D1_releaseObjects();
-
     D3D3_ViewportClearTest();
     p8_primary_test();
     DX1_BackBufferFlipTest();
-- 
2.3.0




More information about the wine-patches mailing list