From 8bbe5304a263338ac6ccada3bdb3612bf968120d Mon Sep 17 00:00:00 2001 From: Erich Hoover Date: Sun, 11 Mar 2007 16:55:06 -0600 Subject: wined3d: Allow SetCursorProperties on existing cursor --- dlls/wined3d/device.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 files changed, 34 insertions(+), 8 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 0998eec..561b7e3 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,44 @@ 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 (IWineD3DSurface_LockRect(pCursorBitmap, &rect, NULL, WINED3DLOCK_READONLY) == WINED3D_OK) + { + GLint format = pSur->glDescription.glFormat; + GLint type = pSur->glDescription.glType; + INT width = This->cursorWidth; + INT height = This->cursorHeight; + void *mem = rect.pBits; + + 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 memory (surface texture copy) into the cursor texture */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, format, type, mem); + checkGLcall("glTexImage2D"); + LEAVE_GL(); + IWineD3DSurface_UnlockRect(pCursorBitmap); + } + else + { + FIXME("A cursor texture was not returned.\n"); + This->cursorTexture = 0; + } } This->xHotSpot = XHotSpot; -- 1.4.1