From 43eea315be3358d887f90289560f8cabbcb5d1a5 Mon Sep 17 00:00:00 2001 From: Erich Hoover Date: Sun, 11 Mar 2007 20:03:39 -0600 Subject: wined3d: Allow SetCursorProperties on existing cursor --- dlls/wined3d/device.c | 49 +++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 41 insertions(+), 8 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 0998eec..919d06d 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -5215,6 +5215,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); @@ -5229,20 +5231,51 @@ 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))) + { + GLint format = pSur->glDescription.glFormat; + GLint type = pSur->glDescription.glType; + char *mem, *bits = (char *)rect.pBits; + INT height = This->cursorHeight; + INT width = This->cursorWidth; + INT bpp = pSur->bytesPerPixel; + 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(pSur->resource.wineD3DDevice, 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, GL_RGBA, 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; -- 1.4.1