Stefan Dösinger : wined3d: Draw the cursor.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jul 24 06:55:06 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: a98ccb543d25cfe7047fe65d91609080ca2ede8b
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=a98ccb543d25cfe7047fe65d91609080ca2ede8b

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Sun Jul 23 00:03:33 2006 +0200

wined3d: Draw the cursor.

---

 dlls/wined3d/device.c          |   33 ++++++++++++++++++++++++---------
 dlls/wined3d/surface.c         |    4 ++--
 dlls/wined3d/swapchain.c       |   14 ++++++++++++++
 dlls/wined3d/wined3d_private.h |   37 ++++++++++++++++++++-----------------
 4 files changed, 60 insertions(+), 28 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index b274393..5928561 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -7435,24 +7435,39 @@ static HRESULT  WINAPI  IWineD3DDeviceIm
                                                         UINT YHotSpot, IWineD3DSurface *pCursorBitmap) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     /* TODO: the use of Impl is deprecated. */
-    /* some basic validation checks */
     IWineD3DSurfaceImpl * pSur = (IWineD3DSurfaceImpl *) pCursorBitmap;
 
     TRACE("(%p) : Spot Pos(%u,%u)\n", This, XHotSpot, YHotSpot);
 
-    if (WINED3DFMT_A8R8G8B8 != pSur->resource.format) {
-      ERR("(%p) : surface(%p) has an invalid format\n", This, pCursorBitmap);
-      return WINED3DERR_INVALIDCALL;
-    }
-    if (32 != pSur->currentDesc.Height || 32 != pSur->currentDesc.Width) {
-      ERR("(%p) : surface(%p) has an invalid size\n", This, pCursorBitmap);
-      return WINED3DERR_INVALIDCALL;
+    /* some basic validation checks */
+    if(pCursorBitmap) {
+        /* MSDN: Cursor must be A8R8G8B8 */
+        if (WINED3DFMT_A8R8G8B8 != pSur->resource.format) {
+            ERR("(%p) : surface(%p) has an invalid format\n", This, pCursorBitmap);
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        /* MSDN: Cursor must be smaller than the display mode */
+        if(pSur->currentDesc.Width > This->ddraw_width ||
+           pSur->currentDesc.Height > This->ddraw_height) {
+            ERR("(%p) : Surface(%p) is %dx%d pixels, but screen res is %ldx%ld\n", This, pSur, pSur->currentDesc.Width, pSur->currentDesc.Height, This->ddraw_width, This->ddraw_height);
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        /* TODO: MSDN: Cursor sizes must be a power of 2 */
+        if(This->mouseCursor) {
+            ((IWineD3DSurfaceImpl *) This->mouseCursor)->Flags &= ~SFLAG_FORCELOAD;
+        }
+        /* This is to tell our texture code to load a SCRATCH surface. This allows us to use out
+         * Texture and Blitting code to draw the cursor
+         */
+        pSur->Flags |= SFLAG_FORCELOAD;
     }
-    /* TODO: make the cursor 'real' */
 
     This->xHotSpot = XHotSpot;
     This->yHotSpot = YHotSpot;
 
+    This->mouseCursor = pCursorBitmap;
     return WINED3D_OK;
 }
 
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 0e90f13..9c2ed60 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1638,7 +1638,7 @@ static HRESULT WINAPI IWineD3DSurfaceImp
     *  these resources cannot be accessed by the Direct3D device nor set as textures or render targets.
     *  However, these resources can always be created, locked, and copied.
     */
-    if (This->resource.pool == WINED3DPOOL_SCRATCH)
+    if (This->resource.pool == WINED3DPOOL_SCRATCH && !(This->Flags & SFLAG_FORCELOAD) )
     {
         FIXME("(%p) Operation not supported for scratch textures\n",This);
         return WINED3DERR_INVALIDCALL;
@@ -2034,7 +2034,7 @@ extern HRESULT WINAPI IWineD3DSurfaceImp
         This->dirtyRect.right  = This->currentDesc.Width;
         This->dirtyRect.bottom = This->currentDesc.Height;
     }
-    TRACE("(%p) : Dirty?%d, Rect:(%ld,%ld,%ld,%ld)\n", This, This->Flags & SFLAG_DIRTY, This->dirtyRect.left,
+    TRACE("(%p) : Dirty?%ld, Rect:(%ld,%ld,%ld,%ld)\n", This, This->Flags & SFLAG_DIRTY, This->dirtyRect.left,
           This->dirtyRect.top, This->dirtyRect.right, This->dirtyRect.bottom);
     /* if the container is a basetexture then mark it dirty. */
     if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index e4b385d..9dde987 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -141,6 +141,20 @@ static HRESULT WINAPI IWineD3DSwapChainI
 
     ENTER_GL();
 
+    /* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */
+    if(This->wineD3DDevice->bCursorVisible && This->wineD3DDevice->mouseCursor) {
+        IWineD3DSurfaceImpl *cursor = (IWineD3DSurfaceImpl *) This->wineD3DDevice->mouseCursor;
+        RECT destRect = {This->wineD3DDevice->xScreenSpace - This->wineD3DDevice->xHotSpot,
+                         This->wineD3DDevice->yScreenSpace - This->wineD3DDevice->yHotSpot,
+                         This->wineD3DDevice->xScreenSpace + cursor->currentDesc.Width - This->wineD3DDevice->xHotSpot,
+                         This->wineD3DDevice->yScreenSpace + cursor->currentDesc.Height - This->wineD3DDevice->yHotSpot};
+        TRACE("Rendering the cursor\n");
+        /* DDBLT_KEYSRC will cause BltOverride to enable the alpha test with GL_NOTEQUAL, 0.0,
+         * which is exactly what we want :-)
+         */
+        IWineD3DSurface_Blt(This->backBuffer[0], &destRect, This->wineD3DDevice->mouseCursor, NULL, DDBLT_KEYSRC, NULL);
+    }
+
     if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
     /* TODO: If only source rect or dest rect are supplied then clip the window to match */
     TRACE("preseting display %p, drawable %ld\n", This->display, This->drawable);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index d542086..c910c67 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -540,6 +540,7 @@ #define                         NEEDS_DI
     UINT                    yHotSpot;
     UINT                    xScreenSpace;
     UINT                    yScreenSpace;
+    IWineD3DSurface        *mouseCursor;
 
     /* Textures for when no other textures are mapped */
     UINT                          dummyTextureName[MAX_TEXTURES];
@@ -853,7 +854,7 @@ struct IWineD3DSurfaceImpl
     UINT                      bytesPerPixel;
 
     /* TODO: move this off into a management class(maybe!) */
-    WORD                      Flags;
+    DWORD                      Flags;
 
     UINT                      pow2Width;
     UINT                      pow2Height;
@@ -930,22 +931,24 @@ DWORD WINAPI IWineD3DSurfaceImpl_GetPitc
 HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface);
 
 /* Surface flags: */
-#define SFLAG_OVERSIZE    0x0001 /* Surface is bigger than gl size, blts only */
-#define SFLAG_CONVERTED   0x0002 /* Converted for color keying or Palettized */
-#define SFLAG_DIBSECTION  0x0004 /* Has a DIB section attached for getdc */
-#define SFLAG_DIRTY       0x0008 /* Surface was locked by the app */
-#define SFLAG_LOCKABLE    0x0010 /* Surface can be locked */
-#define SFLAG_DISCARD     0x0020 /* ??? */
-#define SFLAG_LOCKED      0x0040 /* Surface is locked atm */
-#define SFLAG_ACTIVELOCK  0x0080 /* Not locked, but surface memory is needed */
-#define SFLAG_INTEXTURE   0x0100 /* ??? */
-#define SFLAG_INPBUFFER   0x0200 /* ??? */
-#define SFLAG_NONPOW2     0x0400 /* Surface sizes are not a power of 2 */
-#define SFLAG_DYNLOCK     0x0800 /* Surface is often locked by the app */
-#define SFLAG_DYNCHANGE   0x1800 /* Surface contents are changed very often, implies DYNLOCK */
-#define SFLAG_DCINUSE     0x2000 /* Set between GetDC and ReleaseDC calls */
-#define SFLAG_GLDIRTY     0x4000 /* The opengl texture is more up to date than the surface mem */
-#define SFLAG_LOST        0x8000 /* Surface lost flag for DDraw */
+#define SFLAG_OVERSIZE    0x00000001 /* Surface is bigger than gl size, blts only */
+#define SFLAG_CONVERTED   0x00000002 /* Converted for color keying or Palettized */
+#define SFLAG_DIBSECTION  0x00000004 /* Has a DIB section attached for getdc */
+#define SFLAG_DIRTY       0x00000008 /* Surface was locked by the app */
+#define SFLAG_LOCKABLE    0x00000010 /* Surface can be locked */
+#define SFLAG_DISCARD     0x00000020 /* ??? */
+#define SFLAG_LOCKED      0x00000040 /* Surface is locked atm */
+#define SFLAG_ACTIVELOCK  0x00000080 /* Not locked, but surface memory is needed */
+#define SFLAG_INTEXTURE   0x00000100 /* ??? */
+#define SFLAG_INPBUFFER   0x00000200 /* ??? */
+#define SFLAG_NONPOW2     0x00000400 /* Surface sizes are not a power of 2 */
+#define SFLAG_DYNLOCK     0x00000800 /* Surface is often locked by the app */
+#define SFLAG_DYNCHANGE   0x00001800 /* Surface contents are changed very often, implies DYNLOCK */
+#define SFLAG_DCINUSE     0x00002000 /* Set between GetDC and ReleaseDC calls */
+#define SFLAG_GLDIRTY     0x00004000 /* The opengl texture is more up to date than the surface mem */
+#define SFLAG_LOST        0x00008000 /* Surface lost flag for DDraw */
+#define SFLAG_FORCELOAD   0x00010000 /* To force PreLoading of a scratch cursor */
+
 
 /* In some conditions the surface memory must not be freed:
  * SFLAG_OVERSIZE: Not all data can be kept in GL




More information about the wine-cvs mailing list