WineD3D: Minor cursor fixes

Stefan Dösinger stefan at codeweavers.com
Wed Aug 9 15:23:31 CDT 2006


In an attempt to catch the issue in some games that the gdi cursor is shown on 
top of a cursor drawn by the game I wrote a test case for the cursor. I 
didn't catch the main issue, but just 2 little things

* If no cursor image is set the cursor is never enabled
* The cursor image can't be unset(SetCursorProperties returns an error on 
NULL)
* The GDI cursor is formally not affected.

_Visually_ the gdi cursor disappears after the first successfull 
SetCursorProperties call. Before that it is drawn and can be moved with the 
mouse. After a SetCursorProperties call it disappears, but GetCursorInfo 
still says it is enabled. Any ideas how else the cursor could be hidden? 
Maybe a windows-internal thing?

-------------- next part --------------
From nobody Mon Sep 17 00:00:00 2001
From: Stefan Dösinger <stefan at codeweavers.com>
Date: Wed Aug 9 22:01:46 2006 +0200
Subject: [PATCH] WineD3D: Little cursor fixed + tests

---

 dlls/d3d9/device.c       |    4 ++
 dlls/d3d9/tests/device.c |   83 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/device.c    |    6 ++-
 3 files changed, 91 insertions(+), 2 deletions(-)

56b2285176bfed1a0b142efc25ccc1aea08d03ec
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index ad415a8..6eeaceb 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -147,6 +147,10 @@ static HRESULT  WINAPI  IDirect3DDevice9
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     IDirect3DSurface9Impl *pSurface = (IDirect3DSurface9Impl*)pCursorBitmap;
     TRACE("(%p) Relay\n", This);
+    if(!pCursorBitmap) {
+        WARN("No cursor bitmap, returning WINED3DERR_INVALIDCALL\n");
+        return WINED3DERR_INVALIDCALL;
+    }
     return IWineD3DDevice_SetCursorProperties(This->WineD3DDevice,XHotSpot,YHotSpot,(IWineD3DSurface*)pSurface->wineD3DSurface);
 }
 
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index 9175d27..d126860 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -392,6 +392,88 @@ cleanup:
     DestroyWindow( hwnd );
 }
 
+static void test_cursor(void)
+{
+    HRESULT                      hr;
+    HWND                         hwnd               = NULL;
+    IDirect3D9                  *pD3d               = NULL;
+    IDirect3DDevice9            *pDevice            = NULL;
+    D3DPRESENT_PARAMETERS        d3dpp;
+    D3DDISPLAYMODE               d3ddm;
+    CURSORINFO                   info;
+    IDirect3DSurface9 *cursor = NULL;
+    HCURSOR cur;
+
+    memset(&info, 0, sizeof(info));
+    info.cbSize = sizeof(info);
+    hr = GetCursorInfo(&info);
+    cur = info.hCursor;
+
+    pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
+    ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
+    hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
+    ok(hwnd != NULL, "Failed to create window\n");
+    if (!pD3d || !hwnd) goto cleanup;
+
+    IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
+    ZeroMemory( &d3dpp, sizeof(d3dpp) );
+    d3dpp.Windowed         = TRUE;
+    d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
+    d3dpp.BackBufferFormat = d3ddm.Format;
+
+    hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, hwnd,
+                                  D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
+    ok(SUCCEEDED(hr), "Failed to create IDirect3D9Device (%s)\n", DXGetErrorString9(hr));
+    if (FAILED(hr)) goto cleanup;
+
+    IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &cursor, 0);
+    ok(cursor != NULL, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08lx\n", hr);
+
+    /* Initially hidden */
+    hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
+    ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08lx\n", hr);
+
+    /* Not enabled without a surface*/
+    hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
+    ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08lx\n", hr);
+
+    /* Fails */
+    hr = IDirect3DDevice9_SetCursorProperties(pDevice, 0, 0, NULL);
+    ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetCursorProperties returned %08lx\n", hr);
+
+    hr = IDirect3DDevice9_SetCursorProperties(pDevice, 0, 0, cursor);
+    ok(hr == D3D_OK, "IDirect3DDevice9_SetCursorProperties returned %08lx\n", hr);
+
+    IDirect3DSurface9_Release(cursor);
+
+    memset(&info, 0, sizeof(info));
+    info.cbSize = sizeof(info);
+    hr = GetCursorInfo(&info);
+    ok(hr != 0, "GetCursorInfo returned %08lx\n", hr);
+    ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08lx)\n", info.flags);
+    ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
+
+    /* Still hidden */
+    hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
+    ok(hr == FALSE, "IDirect3DDevice9_ShowCursor returned %08lx\n", hr);
+
+    /* Enabled now*/
+    hr = IDirect3DDevice9_ShowCursor(pDevice, TRUE);
+    ok(hr == TRUE, "IDirect3DDevice9_ShowCursor returned %08lx\n", hr);
+
+    /* GDI cursor unchanged */
+    memset(&info, 0, sizeof(info));
+    info.cbSize = sizeof(info);
+    hr = GetCursorInfo(&info);
+    ok(hr != 0, "GetCursorInfo returned %08lx\n", hr);
+    ok(info.flags & CURSOR_SHOWING, "The gdi cursor is hidden (%08lx)\n", info.flags);
+    ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
+
+cleanup:
+    if(pD3d) IDirect3D9_Release(pD3d);
+    if(pDevice) IDirect3D9_Release(pDevice);
+}
+
 START_TEST(device)
 {
     HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
@@ -402,5 +484,6 @@ START_TEST(device)
         test_swapchain();
         test_refcount();
         test_mipmap_levels();
+        test_cursor();
     }
 }
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 9ac8cf9..eb84173 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -7659,11 +7659,13 @@ static void     WINAPI  IWineD3DDeviceIm
 
 static BOOL     WINAPI  IWineD3DDeviceImpl_ShowCursor(IWineD3DDevice* iface, BOOL bShow) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+    BOOL oldVisible = This->bCursorVisible;
     TRACE("(%p) : visible(%d)\n", This, bShow);
 
-    This->bCursorVisible = bShow;
+    if(This->cursorTexture)
+        This->bCursorVisible = bShow;
 
-    return WINED3D_OK;
+    return oldVisible;
 }
 
 static HRESULT  WINAPI  IWineD3DDeviceImpl_TestCooperativeLevel(IWineD3DDevice* iface) {
-- 
1.2.4



More information about the wine-patches mailing list