Jacek Caban : user32: Use create_cursoricon_object in CURSORICON_CreateIconFromANI.

Alexandre Julliard julliard at winehq.org
Tue Feb 22 16:06:51 CST 2022


Module: wine
Branch: master
Commit: a771eb4405f45e7042ee1b93f7373b2f507d0b71
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=a771eb4405f45e7042ee1b93f7373b2f507d0b71

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Feb 22 13:42:16 2022 +0100

user32: Use create_cursoricon_object in CURSORICON_CreateIconFromANI.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/user32/cursoricon.c | 122 ++++++++++-------------------------------------
 1 file changed, 24 insertions(+), 98 deletions(-)

diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c
index 8b74f7ba4e8..5eb7ddc695a 100644
--- a/dlls/user32/cursoricon.c
+++ b/dlls/user32/cursoricon.c
@@ -109,34 +109,6 @@ static int get_display_bpp(void)
     return ret;
 }
 
-static HICON alloc_icon_handle( BOOL is_ani, UINT num_steps )
-{
-    struct cursoricon_object *obj;
-    HICON handle;
-
-    if (!(obj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj) ))) return NULL;
-    obj->delay = 0;
-    obj->is_ani = is_ani;
-    if (is_ani)
-    {
-        if (!(obj->ani.frames = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                           num_steps * sizeof(*obj->ani.frames) )))
-        {
-            HeapFree( GetProcessHeap(), 0, obj );
-            return NULL;
-        }
-        obj->ani.num_steps = num_steps;
-        obj->ani.num_frames = num_steps; /* changed later for some animated cursors */
-    }
-
-    if (!(handle = alloc_user_handle( &obj->obj, NTUSER_OBJ_ICON )))
-    {
-        if (obj->is_ani) HeapFree( GetProcessHeap(), 0, obj->ani.frames );
-        HeapFree( GetProcessHeap(), 0, obj );
-    }
-    return handle;
-}
-
 static struct cursoricon_object *get_icon_ptr( HICON handle )
 {
     struct cursoricon_object *obj = get_user_handle_ptr( handle, NTUSER_OBJ_ICON );
@@ -990,6 +962,7 @@ BOOL WINAPI NtUserSetCursorIconData( HCURSOR cursor, UNICODE_STRING *module, UNI
             memset( &frame_desc, 0, sizeof(frame_desc) );
             frame_desc.delay  = desc->frame_rates ? desc->frame_rates[i] : desc->delay;
             frame_desc.frames = &desc->frames[frame_id];
+            frame_desc.frames->delay = frame_desc.delay; /* FIXME */
             if (!(obj->ani.frames[i] = alloc_cursoricon_handle( obj->is_icon )) ||
                 !NtUserSetCursorIconData( obj->ani.frames[i], NULL, NULL, &frame_desc ))
             {
@@ -1446,15 +1419,11 @@ static void riff_find_chunk( DWORD chunk_id, DWORD chunk_type, const riff_chunk_
 static HCURSOR CURSORICON_CreateIconFromANI( const BYTE *bits, DWORD bits_size, INT width, INT height,
                                              INT depth, BOOL is_icon, UINT loadflags )
 {
-    struct cursoricon_object *info;
-    DWORD *frame_rates = NULL;
-    DWORD *frame_seq = NULL;
+    struct cursoricon_desc desc = { 0 };
     ani_header header;
-    BOOL use_seq = FALSE;
     HCURSOR cursor;
     UINT i;
     BOOL error = FALSE;
-    HICON *frames;
 
     riff_chunk_t root_chunk = { bits_size, bits };
     riff_chunk_t ACON_chunk = {0};
@@ -1494,8 +1463,7 @@ static HCURSOR CURSORICON_CreateIconFromANI( const BYTE *bits, DWORD bits_size,
         riff_find_chunk( ANI_seq__ID, 0, &ACON_chunk, &seq_chunk );
         if (seq_chunk.data)
         {
-            frame_seq = (DWORD *) seq_chunk.data;
-            use_seq = TRUE;
+            desc.frame_seq = (DWORD *)seq_chunk.data;
         }
         else
         {
@@ -1506,7 +1474,7 @@ static HCURSOR CURSORICON_CreateIconFromANI( const BYTE *bits, DWORD bits_size,
 
     riff_find_chunk( ANI_rate_ID, 0, &ACON_chunk, &rate_chunk );
     if (rate_chunk.data)
-        frame_rates = (DWORD *) rate_chunk.data;
+        desc.frame_rates = (DWORD *)rate_chunk.data;
 
     riff_find_chunk( ANI_fram_ID, ANI_LIST_ID, &ACON_chunk, &fram_chunk );
     if (!fram_chunk.data)
@@ -1515,25 +1483,16 @@ static HCURSOR CURSORICON_CreateIconFromANI( const BYTE *bits, DWORD bits_size,
         return 0;
     }
 
-    cursor = alloc_icon_handle( TRUE, header.num_steps );
-    if (!cursor) return 0;
-    frames = HeapAlloc( GetProcessHeap(), 0, sizeof(*frames) * header.num_frames );
-    if (!frames)
-    {
-        free_icon_handle( cursor );
-        return 0;
-    }
-
-    info = get_icon_ptr( cursor );
-    info->is_icon = is_icon;
-    info->ani.num_frames = header.num_frames;
-
     /* The .ANI stores the display rate in jiffies (1/60s) */
-    info->delay = header.display_rate;
+    desc.delay      = header.display_rate;
+    desc.num_frames = header.num_frames;
+    desc.num_steps  = header.num_steps;
+    if (!(desc.frames = HeapAlloc( GetProcessHeap(), 0, sizeof(*desc.frames) * desc.num_frames )))
+        return 0;
 
     icon_chunk = fram_chunk.data;
     icon_data = fram_chunk.data + (2 * sizeof(DWORD));
-    for (i=0; i<header.num_frames; i++)
+    for (i = 0; i < desc.num_frames; i++)
     {
         const DWORD chunk_size = *(const DWORD *)(icon_chunk + sizeof(DWORD));
         const CURSORICONFILEDIRENTRY *entry;
@@ -1558,29 +1517,28 @@ static HCURSOR CURSORICON_CreateIconFromANI( const BYTE *bits, DWORD bits_size,
             frameHeight = header.height;
         }
 
-        frames[i] = NULL;
-        if (entry->dwDIBOffset < bits + bits_size - icon_data)
+        if (!(error = entry->dwDIBOffset >= bits + bits_size - icon_data))
         {
             bmi = (const BITMAPINFO *) (icon_data + entry->dwDIBOffset);
             /* Grab a frame from the animation */
-            frames[i] = create_icon_from_bmi( bmi, bits + bits_size - (const BYTE *)bmi,
-                                              NULL, NULL, NULL, hotspot,
-                                              is_icon, frameWidth, frameHeight, loadflags );
+            error = !create_icon_frame( bmi, bits + bits_size - (const BYTE *)bmi, hotspot,
+                                        is_icon, frameWidth, frameHeight, loadflags, &desc.frames[i] );
         }
 
-        if (!frames[i])
+        if (error)
         {
-            FIXME_(cursor)("failed to convert animated cursor frame.\n");
-            error = TRUE;
             if (i == 0)
             {
                 FIXME_(cursor)("Completely failed to create animated cursor!\n");
-                info->ani.num_frames = 0;
-                release_user_handle_ptr( info );
-                free_icon_handle( cursor );
-                HeapFree( GetProcessHeap(), 0, frames );
+                HeapFree( GetProcessHeap(), 0, desc.frames );
                 return 0;
             }
+            /* There was an error but we at least decoded the first frame, so just use that frame */
+            FIXME_(cursor)("Error creating animated cursor, only using first frame!\n");
+            while (i > 1) free_icon_frame( &desc.frames[--i] );
+            desc.num_frames = desc.num_steps = 1;
+            desc.frame_seq = NULL;
+            desc.delay = 0;
             break;
         }
 
@@ -1589,41 +1547,9 @@ static HCURSOR CURSORICON_CreateIconFromANI( const BYTE *bits, DWORD bits_size,
         icon_data = icon_chunk + (2 * sizeof(DWORD));
     }
 
-    /* There was an error but we at least decoded the first frame, so just use that frame */
-    if (error)
-    {
-        FIXME_(cursor)("Error creating animated cursor, only using first frame!\n");
-        for (i=1; i < info->ani.num_frames; i++)
-            free_icon_handle( info->ani.frames[i] );
-        use_seq = FALSE;
-        info->delay = 0;
-        info->ani.num_steps = 1;
-        info->ani.num_frames = 1;
-    }
-
-    /* Setup the animated frames in the correct sequence */
-    for (i=0; i < info->ani.num_steps; i++)
-    {
-        DWORD frame_id = use_seq ? frame_seq[i] : i;
-        struct cursoricon_frame *frame;
-
-        if (frame_id >= info->ani.num_frames)
-        {
-            frame_id = info->ani.num_frames-1;
-            ERR_(cursor)("Sequence indicates frame past end of list, corrupt?\n");
-        }
-        info->ani.frames[i] = frames[frame_id];
-        frame = get_icon_frame( info, i );
-        if (frame_rates)
-            frame->delay = frame_rates[i];
-        else
-            frame->delay = ~0;
-        release_icon_frame( info, frame );
-    }
-
-    HeapFree( GetProcessHeap(), 0, frames );
-    release_user_handle_ptr( info );
-
+    cursor = create_cursoricon_object( &desc, is_icon, 0, 0, 0 );
+    if (!cursor) for (i = 0; i < desc.num_frames; i++) free_icon_frame( &desc.frames[i] );
+    HeapFree( GetProcessHeap(), 0, desc.frames );
     return cursor;
 }
 




More information about the wine-cvs mailing list