[1/6] internal cursor / icon memory layout change
H. Verbeet
hverbeet at gmail.com
Tue Apr 18 16:49:50 CDT 2006
This patch adds an header with animation info (number of frames, delay
between frames) to the front of the internal cursor / icon memory
layout, in order to support animated mouse cursors.
Changelog:
- Add a header with animation info to the front of the internal
cursor / icon memory layout
-------------- next part --------------
diff --git a/dlls/user/cursoricon.c b/dlls/user/cursoricon.c
index c093051..5af21a2 100644
--- a/dlls/user/cursoricon.c
+++ b/dlls/user/cursoricon.c
@@ -29,9 +29,17 @@
* Cursors and icons are stored in a global heap block, with the
* following layout:
*
- * CURSORICONINFO info;
- * BYTE[] ANDbits;
- * BYTE[] XORbits;
+ * CURSORANIINFO ani_info;
+ * CURSORICONINFO info0;
+ * BYTE[] ANDbits0;
+ * BYTE[] XORbits0;
+ * CURSORICONINFO info1;
+ * BYTE[] ANDbits1;
+ * BYTE[] XORbits1;
+ * ...
+ * CURSORICONINFO infoN;
+ * BYTE[] ANDbitsN;
+ * BYTE[] XORbitsN;
*
* The bits structures are in the format of a device-dependent bitmap.
*
@@ -39,8 +47,6 @@
* the X client instead of in the server like other bitmaps; however,
* some programs (notably Paint Brush) expect to be able to manipulate
* the bits directly :-(
- *
- * FIXME: what are we going to do with animation and color (bpp > 1) cursors ?!
*/
#include "config.h"
@@ -850,12 +856,16 @@ HICON WINAPI CreateIconFromResourceEx( L
sizeAnd = bmpAnd.bmHeight * bmpAnd.bmWidthBytes;
hObj = GlobalAlloc16( GMEM_MOVEABLE,
- sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
+ sizeof(CURSORANIINFO) + sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
if (hObj)
{
+ CURSORANIINFO *ani_info;
CURSORICONINFO *info;
- info = (CURSORICONINFO *)GlobalLock16( hObj );
+ ani_info = (CURSORANIINFO *)GlobalLock16( hObj );
+ ani_info->num_frames = 1;
+ ani_info->delay = 0;
+ info = (CURSORICONINFO *)(ani_info + 1);
info->ptHotSpot.x = hotspot.x;
info->ptHotSpot.y = hotspot.y;
info->nWidth = bmpXor.bmWidth;
@@ -1331,20 +1341,27 @@ HGLOBAL16 WINAPI CreateCursorIconIndirec
HGLOBAL16 handle;
char *ptr;
int sizeAnd, sizeXor;
+ CURSORANIINFO ani_info;
hInstance = GetExePtr( hInstance ); /* Make it a module handle */
if (!lpXORbits || !lpANDbits || info->bPlanes != 1) return 0;
+ ani_info.num_frames = 1;
+ ani_info.delay = 0;
info->nWidthBytes = get_bitmap_width_bytes(info->nWidth,info->bBitsPerPixel);
sizeXor = info->nHeight * info->nWidthBytes;
sizeAnd = info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
if (!(handle = GlobalAlloc16( GMEM_MOVEABLE,
- sizeof(CURSORICONINFO) + sizeXor + sizeAnd)))
+ sizeof(CURSORANIINFO) + sizeof(CURSORICONINFO) + sizeXor + sizeAnd)))
return 0;
FarSetOwner16( handle, hInstance );
ptr = (char *)GlobalLock16( handle );
+ memcpy( ptr, &ani_info, sizeof(CURSORANIINFO));
+ ptr += sizeof(CURSORANIINFO);
memcpy( ptr, info, sizeof(*info) );
- memcpy( ptr + sizeof(CURSORICONINFO), lpANDbits, sizeAnd );
- memcpy( ptr + sizeof(CURSORICONINFO) + sizeAnd, lpXORbits, sizeXor );
+ ptr += sizeof(CURSORICONINFO);
+ memcpy( ptr, lpANDbits, sizeAnd );
+ ptr += sizeAnd;
+ memcpy( ptr, lpXORbits, sizeXor );
GlobalUnlock16( handle );
return handle;
}
@@ -1443,11 +1460,13 @@ BOOL WINAPI DestroyCursor( HCURSOR hCurs
BOOL WINAPI DrawIcon( HDC hdc, INT x, INT y, HICON hIcon )
{
CURSORICONINFO *ptr;
+ CURSORANIINFO *ani_info;
HDC hMemDC;
HBITMAP hXorBits, hAndBits;
COLORREF oldFg, oldBg;
- if (!(ptr = (CURSORICONINFO *)GlobalLock16(HICON_16(hIcon)))) return FALSE;
+ if (!(ani_info = (CURSORANIINFO *)GlobalLock16(HICON_16(hIcon)))) return FALSE;
+ ptr = (CURSORICONINFO *)(ani_info + 1);
if (!(hMemDC = CreateCompatibleDC( hdc ))) return FALSE;
hAndBits = CreateBitmap( ptr->nWidth, ptr->nHeight, 1, 1,
(char *)(ptr+1) );
@@ -1513,7 +1532,7 @@ HCURSOR WINAPI SetCursor( HCURSOR hCurso
/* Change the cursor shape only if it is visible */
if (thread_info->cursor_count >= 0)
{
- USER_Driver->pSetCursor( (CURSORICONINFO*)GlobalLock16(HCURSOR_16(hCursor)) );
+ USER_Driver->pSetCursor( (CURSORANIINFO*)GlobalLock16(HCURSOR_16(hCursor)) );
GlobalUnlock16(HCURSOR_16(hCursor));
}
return hOldCursor;
@@ -1532,7 +1551,7 @@ INT WINAPI ShowCursor( BOOL bShow )
{
if (++thread_info->cursor_count == 0) /* Show it */
{
- USER_Driver->pSetCursor((CURSORICONINFO*)GlobalLock16(HCURSOR_16(thread_info->cursor)));
+ USER_Driver->pSetCursor((CURSORANIINFO*)GlobalLock16(HCURSOR_16(thread_info->cursor)));
GlobalUnlock16(HCURSOR_16(thread_info->cursor));
}
}
@@ -1760,12 +1779,14 @@ HICON WINAPI LoadIconA(HINSTANCE hInstan
*/
BOOL WINAPI GetIconInfo(HICON hIcon, PICONINFO iconinfo)
{
+ CURSORANIINFO *caniinfo;
CURSORICONINFO *ciconinfo;
INT height;
- ciconinfo = GlobalLock16(HICON_16(hIcon));
- if (!ciconinfo)
+ caniinfo = (CURSORANIINFO *)GlobalLock16(HICON_16(hIcon));
+ if (!caniinfo)
return FALSE;
+ ciconinfo = (CURSORICONINFO *)(caniinfo + 1);
if ( (ciconinfo->ptHotSpot.x == ICON_HOTSPOT) &&
(ciconinfo->ptHotSpot.y == ICON_HOTSPOT) )
@@ -1820,12 +1841,16 @@ HICON WINAPI CreateIconIndirect(PICONINF
sizeAnd = bmpAnd.bmHeight * bmpAnd.bmWidthBytes;
hObj = GlobalAlloc16( GMEM_MOVEABLE,
- sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
+ sizeof(CURSORANIINFO) + sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
if (hObj)
{
+ CURSORANIINFO *ani_info;
CURSORICONINFO *info;
- info = (CURSORICONINFO *)GlobalLock16( hObj );
+ ani_info = (CURSORANIINFO *)GlobalLock16( hObj );
+ ani_info->num_frames = 1;
+ ani_info->delay = 0;
+ info = (CURSORICONINFO *)(ani_info + 1);
/* If we are creating an icon, the hotspot is unused */
if (iconinfo->fIcon)
@@ -1890,12 +1915,13 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0,
INT cxWidth, INT cyWidth, UINT istep,
HBRUSH hbr, UINT flags )
{
- CURSORICONINFO *ptr = (CURSORICONINFO *)GlobalLock16(HICON_16(hIcon));
+ CURSORANIINFO *ani_info = (CURSORANIINFO *)GlobalLock16(HICON_16(hIcon));
+ CURSORICONINFO *ptr = (CURSORICONINFO *)(ani_info + 1);
HDC hDC_off = 0, hMemDC;
BOOL result = FALSE, DoOffscreen;
HBITMAP hB_off = 0, hOld = 0;
- if (!ptr) return FALSE;
+ if (!ani_info) return FALSE;
TRACE_(icon)("(hdc=%p,pos=%d.%d,hicon=%p,extend=%d.%d,istep=%d,br=%p,flags=0x%08x)\n",
hdc,x0,y0,hIcon,cxWidth,cyWidth,istep,hbr,flags );
diff --git a/dlls/user/display.c b/dlls/user/display.c
index 5455022..d054eed 100644
--- a/dlls/user/display.c
+++ b/dlls/user/display.c
@@ -50,7 +50,7 @@ WORD WINAPI DISPLAY_Inquire(LPCURSORINFO
/***********************************************************************
* SetCursor (DISPLAY.102)
*/
-VOID WINAPI DISPLAY_SetCursor( struct tagCURSORICONINFO *lpCursor )
+VOID WINAPI DISPLAY_SetCursor( struct tagCURSORANIINFO *lpCursor )
{
USER_Driver->pSetCursor(lpCursor);
}
diff --git a/dlls/user/driver.c b/dlls/user/driver.c
index 4a31049..27b9016 100644
--- a/dlls/user/driver.c
+++ b/dlls/user/driver.c
@@ -216,7 +216,7 @@ static SHORT nulldrv_VkKeyScanEx( WCHAR
return -1;
}
-static void nulldrv_SetCursor( struct tagCURSORICONINFO *info )
+static void nulldrv_SetCursor( struct tagCURSORANIINFO *info )
{
}
@@ -538,7 +538,7 @@ static SHORT loaderdrv_VkKeyScanEx( WCHA
return load_driver()->pVkKeyScanEx( ch, layout );
}
-static void loaderdrv_SetCursor( struct tagCURSORICONINFO *info )
+static void loaderdrv_SetCursor( struct tagCURSORANIINFO *info )
{
load_driver()->pSetCursor( info );
}
diff --git a/dlls/user/static.c b/dlls/user/static.c
index 4c38e1e..da530f6 100644
--- a/dlls/user/static.c
+++ b/dlls/user/static.c
@@ -120,14 +120,16 @@ const struct builtin_class_descr STATIC_
static HICON STATIC_SetIcon( HWND hwnd, HICON hicon, DWORD style )
{
HICON prevIcon;
+ CURSORANIINFO * ani_info;
CURSORICONINFO * info;
if ((style & SS_TYPEMASK) != SS_ICON) return 0;
- info = hicon?(CURSORICONINFO *) GlobalLock16(HICON_16(hicon)):NULL;
- if (hicon && !info) {
- WARN("hicon != 0, but info == 0\n");
+ ani_info = hicon?(CURSORANIINFO *)GlobalLock16(HICON_16(hicon)):NULL;
+ if (hicon && !ani_info) {
+ WARN("hicon != 0, but ani_info == 0\n");
return 0;
}
+ info = (CURSORICONINFO *)(ani_info + 1);
prevIcon = (HICON)SetWindowLongPtrW( hwnd, HICON_GWL_OFFSET, (LONG_PTR)hicon );
if (hicon && !(style & SS_CENTERIMAGE) && !(style & SS_REALSIZECONTROL))
{
@@ -146,7 +148,7 @@ static HICON STATIC_SetIcon( HWND hwnd,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
}
}
- if (info) GlobalUnlock16(HICON_16(hicon));
+ if (ani_info) GlobalUnlock16(HICON_16(hicon));
return prevIcon;
}
@@ -741,18 +743,20 @@ static void STATIC_PaintIconfn( HWND hwn
RECT rc, iconRect;
HBRUSH hbrush;
HICON hIcon;
+ CURSORANIINFO * ani_info;
CURSORICONINFO * info;
GetClientRect( hwnd, &rc );
hbrush = STATIC_SendWmCtlColorStatic(hwnd, hdc);
hIcon = (HICON)GetWindowLongPtrW( hwnd, HICON_GWL_OFFSET );
- info = hIcon ? (CURSORICONINFO *)GlobalLock16(HICON_16(hIcon)) : NULL;
- if (!hIcon || !info)
+ ani_info = hIcon ? (CURSORANIINFO *)GlobalLock16(HICON_16(hIcon)) : NULL;
+ if (!hIcon || !ani_info)
{
FillRect(hdc, &rc, hbrush);
}
else
{
+ info = (CURSORICONINFO *)(ani_info + 1);
if (style & SS_CENTERIMAGE)
{
iconRect.left = (rc.right - rc.left) / 2 - info->nWidth / 2;
@@ -768,7 +772,7 @@ static void STATIC_PaintIconfn( HWND hwn
rc.bottom - rc.top, 0, NULL, DI_NORMAL );
}
}
- if (info) GlobalUnlock16(HICON_16(hIcon));
+ if (ani_info) GlobalUnlock16(HICON_16(hIcon));
}
static void STATIC_PaintBitmapfn(HWND hwnd, HDC hdc, DWORD style )
diff --git a/dlls/user/uitools.c b/dlls/user/uitools.c
index 9e8f3bb..72fc13c 100644
--- a/dlls/user/uitools.c
+++ b/dlls/user/uitools.c
@@ -1597,6 +1597,7 @@ static BOOL UITOOLS_DrawState(HDC hdc, H
if(!cx || !cy)
{
SIZE s;
+ CURSORANIINFO *ani_info;
CURSORICONINFO *ici;
BITMAP bm;
@@ -1612,8 +1613,9 @@ static BOOL UITOOLS_DrawState(HDC hdc, H
break;
case DST_ICON:
- ici = (CURSORICONINFO *)GlobalLock16((HGLOBAL16)lp);
- if(!ici) return FALSE;
+ ani_info = (CURSORANIINFO *)GlobalLock16((HGLOBAL16)lp);
+ if(!ani_info) return FALSE;
+ ici = (CURSORICONINFO *)(ani_info + 1);
s.cx = ici->nWidth;
s.cy = ici->nHeight;
GlobalUnlock16((HGLOBAL16)lp);
diff --git a/dlls/user/user_private.h b/dlls/user/user_private.h
index 5d205aa..7fb2797 100644
--- a/dlls/user/user_private.h
+++ b/dlls/user/user_private.h
@@ -97,7 +97,7 @@ enum wine_internal_message
WM_WINE_LAST_DRIVER_MSG = 0x80001fff
};
-struct tagCURSORICONINFO;
+struct tagCURSORANIINFO;
typedef struct tagUSER_DRIVER {
/* keyboard functions */
@@ -115,7 +115,7 @@ typedef struct tagUSER_DRIVER {
BOOL (*pUnloadKeyboardLayout)(HKL);
SHORT (*pVkKeyScanEx)(WCHAR, HKL);
/* mouse functions */
- void (*pSetCursor)(struct tagCURSORICONINFO *);
+ void (*pSetCursor)(struct tagCURSORANIINFO *);
BOOL (*pGetCursorPos)(LPPOINT);
BOOL (*pSetCursorPos)(INT,INT);
/* screen saver functions */
diff --git a/dlls/x11drv/mouse.c b/dlls/x11drv/mouse.c
index 43b0fb4..e9ae7f8 100644
--- a/dlls/x11drv/mouse.c
+++ b/dlls/x11drv/mouse.c
@@ -359,13 +359,14 @@ void X11DRV_send_mouse_input( HWND hwnd,
*
* Create an X cursor from a Windows one.
*/
-static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
+static Cursor create_cursor( Display *display, CURSORANIINFO *ani_info )
{
Pixmap pixmapBits, pixmapMask, pixmapMaskInv, pixmapAll;
XColor fg, bg;
Cursor cursor = None;
+ CURSORICONINFO *ptr = (CURSORICONINFO *)(ani_info + 1);
- if (!ptr) /* Create an empty cursor */
+ if (!ani_info) /* Create an empty cursor */
{
static const char data[] = { 0 };
@@ -647,7 +648,7 @@ static Cursor create_cursor( Display *di
/***********************************************************************
* SetCursor (X11DRV.@)
*/
-void X11DRV_SetCursor( CURSORICONINFO *lpCursor )
+void X11DRV_SetCursor( CURSORANIINFO *lpCursor )
{
Cursor cursor;
diff --git a/dlls/x11drv/x11drv.h b/dlls/x11drv/x11drv.h
index d259c86..cb01948 100644
--- a/dlls/x11drv/x11drv.h
+++ b/dlls/x11drv/x11drv.h
@@ -66,7 +66,7 @@ typedef int Status;
#define MAX_PIXELFORMATS 8
-struct tagCURSORICONINFO;
+struct tagCURSORANIINFO;
struct dce;
extern void wine_tsx11_lock(void);
@@ -664,7 +664,7 @@ extern XContext winContext;
extern void X11DRV_InitClipboard(void);
extern void X11DRV_AcquireClipboard(HWND hWndClipWindow);
extern void X11DRV_SetFocus( HWND hwnd );
-extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr );
+extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORANIINFO *ptr );
extern void X11DRV_InitKeyboard(void);
extern void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time,
DWORD dwExtraInfo, UINT injected_flags );
diff --git a/include/wine/winuser16.h b/include/wine/winuser16.h
index e11f7fd..d51dde5 100644
--- a/include/wine/winuser16.h
+++ b/include/wine/winuser16.h
@@ -148,6 +148,12 @@ typedef struct
/* Cursors / Icons */
+typedef struct tagCURSORANIINFO
+{
+ DWORD num_frames;
+ DWORD delay;
+} CURSORANIINFO;
+
typedef struct tagCURSORICONINFO
{
POINT16 ptHotSpot;
diff --git a/programs/progman/grpfile.c b/programs/progman/grpfile.c
index 5b9d11f..97d2d06 100644
--- a/programs/progman/grpfile.c
+++ b/programs/progman/grpfile.c
@@ -422,7 +422,7 @@ BOOL GRPFILE_WriteGroupFile(HLOCAL hGrou
static VOID GRPFILE_CalculateSizes(PROGRAM *program,
INT *Progs, INT *Icons)
{
- CURSORICONINFO *iconinfo = LocalLock(program->hIcon);
+ CURSORICONINFO *iconinfo = (CURSORICONINFO *)((CURSORANIINFO *)LocalLock(program->hIcon) + 1);
INT sizeXor = iconinfo->nHeight * iconinfo->nWidthBytes;
INT sizeAnd = iconinfo->nHeight * ((iconinfo->nWidth + 15) / 16 * 2);
@@ -601,7 +601,7 @@ static BOOL GRPFILE_DoWriteGroupFile(HFI
while(hProgram)
{
PROGRAM *program = LocalLock(hProgram);
- CURSORICONINFO *iconinfo = LocalLock(program->hIcon);
+ CURSORICONINFO *iconinfo = (CURSORICONINFO *)((CURSORANIINFO *)LocalLock(program->hIcon) + 1);
LPCSTR Name = LocalLock(program->hName);
LPCSTR CmdLine = LocalLock(program->hCmdLine);
LPCSTR IconFile = LocalLock(program->hIconFile);
@@ -640,7 +640,7 @@ static BOOL GRPFILE_DoWriteGroupFile(HFI
while(hProgram)
{
PROGRAM *program = LocalLock(hProgram);
- CURSORICONINFO *iconinfo = LocalLock(program->hIcon);
+ CURSORICONINFO *iconinfo = (CURSORICONINFO *)((CURSORANIINFO *)LocalLock(program->hIcon) + 1);
LPVOID XorBits, AndBits;
INT sizeXor = iconinfo->nHeight * iconinfo->nWidthBytes;
INT sizeAnd = iconinfo->nHeight * ((iconinfo->nWidth + 15) / 16 * 2);
More information about the wine-patches
mailing list