[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