wined3d: Allow SetCursorProperties on existing cursor

Erich Hoover ehoover at mines.edu
Mon Mar 12 21:44:22 CDT 2007


Skipped content of type multipart/alternative-------------- next part --------------
From 3555a5b39b0542febb38e43d7aef5adfe9ffc638 Mon Sep 17 00:00:00 2001
From: Erich Hoover <ehoover at mediaserver.(none)>
Date: Mon, 12 Mar 2007 12:34:51 -0600
Subject: wined3d: Allow SetCursorProperties on existing cursor
---
 dlls/wined3d/device.c          |   52 ++++++++++++++++++++++++++++++++++------
 dlls/wined3d/surface.c         |    2 +-
 dlls/wined3d/wined3d_private.h |    5 ++--
 3 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 10b03bf..00b821a 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5242,6 +5242,8 @@ static HRESULT  WINAPI  IWineD3DDeviceIm
     }
 
     if(pCursorBitmap) {
+        WINED3DLOCKED_RECT rect;
+        
         /* MSDN: Cursor must be A8R8G8B8 */
         if (WINED3DFMT_A8R8G8B8 != pSur->resource.format) {
             ERR("(%p) : surface(%p) has an invalid format\n", This, pCursorBitmap);
@@ -5256,20 +5258,54 @@ static HRESULT  WINAPI  IWineD3DDeviceIm
         }
 
         /* TODO: MSDN: Cursor sizes must be a power of 2 */
-        /* 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;
-        IWineD3DSurface_PreLoad(pCursorBitmap);
-        pSur->Flags &= ~SFLAG_FORCELOAD;
+
         /* Do not store the surface's pointer because the application may release
          * it after setting the cursor image. Windows doesn't addref the set surface, so we can't
          * do this either without creating circular refcount dependencies. Copy out the gl texture instead.
          */
-        This->cursorTexture = pSur->glDescription.textureName;
         This->cursorWidth = pSur->currentDesc.Width;
         This->cursorHeight = pSur->currentDesc.Height;
-        pSur->glDescription.textureName = 0; /* Prevent the texture from being changed or deleted */
+        if (SUCCEEDED(IWineD3DSurface_LockRect(pCursorBitmap, &rect, NULL, WINED3DLOCK_READONLY)))
+        {
+            const PixelFormatDesc *tableEntry = getFormatDescEntry(WINED3DFMT_A8R8G8B8);
+            char *mem, *bits = (char *)rect.pBits;
+            GLint intfmt = tableEntry->glInternal;
+            GLint format = tableEntry->glFormat;
+            GLint type = tableEntry->glType;
+            INT height = This->cursorHeight;
+            INT width = This->cursorWidth;
+            INT bpp = tableEntry->bpp;
+            INT i;
+
+            /* Reformat the texture memory (pitch and width can be different) */
+            mem = HeapAlloc(GetProcessHeap(), 0, width * height * bpp);
+            for(i = 0; i < height; i++)
+                memcpy(&mem[width * bpp * i], &bits[rect.Pitch * i], width * bpp);
+            IWineD3DSurface_UnlockRect(pCursorBitmap);
+            ENTER_GL();
+            /* Make sure that a proper texture unit is selected */
+            if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+                GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
+                checkGLcall("glActiveTextureARB");
+            }
+            IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(0));
+            /* Create a new cursor texture */
+            glGenTextures(1, &This->cursorTexture);
+            checkGLcall("glGenTextures");
+            glBindTexture(GL_TEXTURE_2D, This->cursorTexture);
+            checkGLcall("glBindTexture");
+            /* Copy the bitmap memory into the cursor texture */
+            glTexImage2D(GL_TEXTURE_2D, 0, intfmt, width, height, 0, format, type, mem);
+            HeapFree(GetProcessHeap(), 0, mem);
+            checkGLcall("glTexImage2D");
+            LEAVE_GL();
+        }
+        else
+        {
+            FIXME("A cursor texture was not returned.\n");
+            This->cursorTexture = 0;
+        }
+
     }
 
     This->xHotSpot = XHotSpot;
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index c8d39f6..d99d911 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1716,7 +1716,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 && !(This->Flags & SFLAG_FORCELOAD) )
+    if (This->resource.pool == WINED3DPOOL_SCRATCH )
     {
         FIXME("(%p) Operation not supported for scratch textures\n",This);
         return WINED3DERR_INVALIDCALL;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9d80d83..5d99668 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1116,9 +1116,8 @@ #define SFLAG_DYNLOCK     0x00000400 /* 
 #define SFLAG_DYNCHANGE   0x00000C00 /* Surface contents are changed very often, implies DYNLOCK */
 #define SFLAG_DCINUSE     0x00001000 /* Set between GetDC and ReleaseDC calls */
 #define SFLAG_LOST        0x00002000 /* Surface lost flag for DDraw */
-#define SFLAG_FORCELOAD   0x00004000 /* To force PreLoading of a scratch cursor */
-#define SFLAG_USERPTR     0x00008000 /* The application allocated the memory for this surface */
-#define SFLAG_GLCKEY      0x00010000 /* The gl texture was created with a color key */
+#define SFLAG_USERPTR     0x00004000 /* The application allocated the memory for this surface */
+#define SFLAG_GLCKEY      0x00008000 /* The gl texture was created with a color key */
 
 /* In some conditions the surface memory must not be freed:
  * SFLAG_OVERSIZE: Not all data can be kept in GL
-- 
1.4.1


More information about the wine-patches mailing list