mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-01 07:03:37 +00:00
user32: Implement semi-stub of GetCursorFrameInfo.
This commit is contained in:
parent
7b0ab606e2
commit
e776f3ccf7
|
@ -101,7 +101,7 @@ struct cursoricon_object
|
|||
UINT height;
|
||||
POINT hotspot;
|
||||
UINT num_frames; /* number of frames in the icon/cursor */
|
||||
UINT ms_delay; /* delay between frames (in milliseconds) */
|
||||
UINT delay; /* delay between frames (in jiffies) */
|
||||
struct cursoricon_frame frames[1]; /* icon frame information */
|
||||
};
|
||||
|
||||
|
@ -111,6 +111,7 @@ static HICON alloc_icon_handle( UINT num_frames )
|
|||
FIELD_OFFSET( struct cursoricon_object, frames[num_frames] ));
|
||||
|
||||
if (!obj) return 0;
|
||||
obj->delay = 0;
|
||||
obj->num_frames = num_frames;
|
||||
return alloc_user_handle( &obj->obj, USER_ICON );
|
||||
}
|
||||
|
@ -1027,8 +1028,8 @@ static HCURSOR CURSORICON_CreateIconFromANI( const LPBYTE bits, DWORD bits_size,
|
|||
info = get_icon_ptr( cursor );
|
||||
info->is_icon = FALSE;
|
||||
|
||||
/* The .ANI stores the display rate in 1/60s, we store the delay between frames in ms */
|
||||
info->ms_delay = (100 * header.display_rate) / 6;
|
||||
/* The .ANI stores the display rate in jiffies (1/60s) */
|
||||
info->delay = header.display_rate;
|
||||
|
||||
icon_chunk = fram_chunk.data;
|
||||
icon_data = fram_chunk.data + (2 * sizeof(DWORD));
|
||||
|
@ -1084,7 +1085,7 @@ static HCURSOR CURSORICON_CreateIconFromANI( const LPBYTE bits, DWORD bits_size,
|
|||
if (info->frames[i].alpha) DeleteObject( info->frames[i].alpha );
|
||||
}
|
||||
info->num_frames = 1;
|
||||
info->ms_delay = 0;
|
||||
info->delay = 0;
|
||||
}
|
||||
info->width = header.width;
|
||||
info->height = header.height;
|
||||
|
@ -1696,6 +1697,40 @@ HICON WINAPI LoadIconA(HINSTANCE hInstance, LPCSTR name)
|
|||
LR_SHARED | LR_DEFAULTSIZE );
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* GetCursorFrameInfo (USER32.@)
|
||||
*/
|
||||
HCURSOR WINAPI GetCursorFrameInfo(HCURSOR hCursor, DWORD unk1, DWORD rate_index_num, DWORD *rate_jiffies, DWORD *is_static)
|
||||
{
|
||||
struct cursoricon_object *ptr;
|
||||
HCURSOR ret = 0;
|
||||
|
||||
if (rate_jiffies == NULL || is_static == NULL) return 0;
|
||||
|
||||
if (!(ptr = get_icon_ptr( hCursor ))) return 0;
|
||||
|
||||
FIXME("semi-stub! %p => %d %d %p %p\n", hCursor, unk1, rate_index_num, rate_jiffies, is_static);
|
||||
|
||||
if (ptr->num_frames == 1 || rate_index_num == 0)
|
||||
{
|
||||
ret = hCursor;
|
||||
if (ptr->num_frames == 1)
|
||||
{
|
||||
*rate_jiffies = 0;
|
||||
*is_static = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*is_static = ~0;
|
||||
*rate_jiffies = ptr->delay;
|
||||
}
|
||||
}
|
||||
|
||||
release_icon_ptr( hCursor, ptr );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* GetIconInfo (USER32.@)
|
||||
*/
|
||||
|
|
|
@ -116,9 +116,18 @@ typedef struct {
|
|||
riff_header_t header; /* RIFF animated cursor header */
|
||||
riff_list_t frame_list; /* RIFF animated cursor frame list info */
|
||||
riff_icon32x32x32_t frames[1]; /* array of animated cursor frames */
|
||||
} riff_cursor_t;
|
||||
} riff_cursor1_t;
|
||||
|
||||
riff_cursor_t empty_anicursor = {
|
||||
typedef struct {
|
||||
DWORD chunk_id; /* ANI_RIFF_ID */
|
||||
DWORD chunk_size; /* actual size of data */
|
||||
DWORD chunk_type; /* ANI_ACON_ID */
|
||||
riff_header_t header; /* RIFF animated cursor header */
|
||||
riff_list_t frame_list; /* RIFF animated cursor frame list info */
|
||||
riff_icon32x32x32_t frames[3]; /* array of animated cursor frames */
|
||||
} riff_cursor3_t;
|
||||
|
||||
riff_cursor1_t empty_anicursor = {
|
||||
ANI_RIFF_ID,
|
||||
sizeof(empty_anicursor) - sizeof(DWORD)*2,
|
||||
ANI_ACON_ID,
|
||||
|
@ -183,6 +192,145 @@ riff_cursor_t empty_anicursor = {
|
|||
}
|
||||
};
|
||||
|
||||
riff_cursor3_t empty_anicursor3 = {
|
||||
ANI_RIFF_ID,
|
||||
sizeof(empty_anicursor3) - sizeof(DWORD)*2,
|
||||
ANI_ACON_ID,
|
||||
{
|
||||
ANI_anih_ID,
|
||||
sizeof(ani_header),
|
||||
{
|
||||
sizeof(ani_header),
|
||||
3, /* frames */
|
||||
1, /* steps */
|
||||
32, /* width */
|
||||
32, /* height */
|
||||
32, /* depth */
|
||||
1, /* planes */
|
||||
0xbeef, /* display rate in jiffies */
|
||||
ANI_FLAG_ICON /* flags */
|
||||
}
|
||||
},
|
||||
{
|
||||
ANI_LIST_ID,
|
||||
sizeof(riff_icon32x32x32_t)*(3 /*frames*/) + sizeof(DWORD),
|
||||
ANI_fram_ID,
|
||||
},
|
||||
{
|
||||
{
|
||||
ANI_icon_ID,
|
||||
sizeof(ani_frame32x32x32),
|
||||
{
|
||||
{
|
||||
0x0, /* reserved */
|
||||
0, /* type: icon(1), cursor(2) */
|
||||
1, /* count */
|
||||
{
|
||||
{
|
||||
32, /* width */
|
||||
32, /* height */
|
||||
0, /* color count */
|
||||
0x0, /* reserved */
|
||||
16, /* x hotspot */
|
||||
16, /* y hotspot */
|
||||
sizeof(ani_data32x32x32), /* DIB size */
|
||||
sizeof(CURSORICONFILEDIR) /* DIB offset */
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
sizeof(BITMAPINFOHEADER), /* structure for DIB-type data */
|
||||
32, /* width */
|
||||
32*2, /* actual height times two */
|
||||
1, /* planes */
|
||||
32, /* bpp */
|
||||
BI_RGB, /* compression */
|
||||
0, /* image size */
|
||||
0, /* biXPelsPerMeter */
|
||||
0, /* biYPelsPerMeter */
|
||||
0, /* biClrUsed */
|
||||
0 /* biClrImportant */
|
||||
},
|
||||
{ /* DIB data: left uninitialized */ }
|
||||
}
|
||||
},
|
||||
{
|
||||
ANI_icon_ID,
|
||||
sizeof(ani_frame32x32x32),
|
||||
{
|
||||
{
|
||||
0x0, /* reserved */
|
||||
0, /* type: icon(1), cursor(2) */
|
||||
1, /* count */
|
||||
{
|
||||
{
|
||||
32, /* width */
|
||||
32, /* height */
|
||||
0, /* color count */
|
||||
0x0, /* reserved */
|
||||
16, /* x hotspot */
|
||||
16, /* y hotspot */
|
||||
sizeof(ani_data32x32x32), /* DIB size */
|
||||
sizeof(CURSORICONFILEDIR) /* DIB offset */
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
sizeof(BITMAPINFOHEADER), /* structure for DIB-type data */
|
||||
32, /* width */
|
||||
32*2, /* actual height times two */
|
||||
1, /* planes */
|
||||
32, /* bpp */
|
||||
BI_RGB, /* compression */
|
||||
0, /* image size */
|
||||
0, /* biXPelsPerMeter */
|
||||
0, /* biYPelsPerMeter */
|
||||
0, /* biClrUsed */
|
||||
0 /* biClrImportant */
|
||||
},
|
||||
{ /* DIB data: left uninitialized */ }
|
||||
}
|
||||
},
|
||||
{
|
||||
ANI_icon_ID,
|
||||
sizeof(ani_frame32x32x32),
|
||||
{
|
||||
{
|
||||
0x0, /* reserved */
|
||||
0, /* type: icon(1), cursor(2) */
|
||||
1, /* count */
|
||||
{
|
||||
{
|
||||
32, /* width */
|
||||
32, /* height */
|
||||
0, /* color count */
|
||||
0x0, /* reserved */
|
||||
16, /* x hotspot */
|
||||
16, /* y hotspot */
|
||||
sizeof(ani_data32x32x32), /* DIB size */
|
||||
sizeof(CURSORICONFILEDIR) /* DIB offset */
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
sizeof(BITMAPINFOHEADER), /* structure for DIB-type data */
|
||||
32, /* width */
|
||||
32*2, /* actual height times two */
|
||||
1, /* planes */
|
||||
32, /* bpp */
|
||||
BI_RGB, /* compression */
|
||||
0, /* image size */
|
||||
0, /* biXPelsPerMeter */
|
||||
0, /* biYPelsPerMeter */
|
||||
0, /* biClrUsed */
|
||||
0 /* biClrImportant */
|
||||
},
|
||||
{ /* DIB data: left uninitialized */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#include "poppack.h"
|
||||
|
||||
static char **test_argv;
|
||||
|
@ -1291,6 +1439,118 @@ static void test_CreateIconFromResource(void)
|
|||
ok(error == 0xdeadbeef, "Last error: %u\n", error);
|
||||
}
|
||||
|
||||
static HCURSOR WINAPI (*pGetCursorFrameInfo)(HCURSOR hCursor, VOID *unk1, VOID *unk2, VOID *unk3, VOID *unk4);
|
||||
static void test_GetCursorFrameInfo(void)
|
||||
{
|
||||
DWORD unk1, unk2, unk3, unk4;
|
||||
BITMAPINFOHEADER *icon_header;
|
||||
INT16 *hotspot;
|
||||
HANDLE h1, h2;
|
||||
BOOL ret;
|
||||
|
||||
if (!pGetCursorFrameInfo)
|
||||
{
|
||||
win_skip( "GetCursorFrameInfo not supported, skipping tests.\n" );
|
||||
return;
|
||||
}
|
||||
#define ICON_RES_WIDTH 32
|
||||
#define ICON_RES_HEIGHT 32
|
||||
#define ICON_RES_AND_SIZE (ICON_WIDTH*ICON_HEIGHT/8)
|
||||
#define ICON_RES_BPP 32
|
||||
#define ICON_RES_SIZE \
|
||||
(sizeof(BITMAPINFOHEADER) + ICON_AND_SIZE + ICON_AND_SIZE*ICON_BPP)
|
||||
#define CRSR_RES_SIZE (2*sizeof(INT16) + ICON_RES_SIZE)
|
||||
|
||||
/* Set icon data. */
|
||||
hotspot = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, CRSR_RES_SIZE);
|
||||
|
||||
/* Cursor resources have an extra hotspot, icon resources not. */
|
||||
hotspot[0] = 3;
|
||||
hotspot[1] = 3;
|
||||
|
||||
icon_header = (BITMAPINFOHEADER *) (hotspot + 2);
|
||||
icon_header->biSize = sizeof(BITMAPINFOHEADER);
|
||||
icon_header->biWidth = ICON_WIDTH;
|
||||
icon_header->biHeight = ICON_HEIGHT*2;
|
||||
icon_header->biPlanes = 1;
|
||||
icon_header->biBitCount = ICON_BPP;
|
||||
icon_header->biSizeImage = 0; /* Uncompressed bitmap. */
|
||||
|
||||
/* Creating a static cursor. */
|
||||
SetLastError(0xdeadbeef);
|
||||
h1 = CreateIconFromResource((PBYTE) hotspot, CRSR_RES_SIZE, FALSE, 0x00030000);
|
||||
ok(h1 != NULL, "Create cursor failed.\n");
|
||||
|
||||
/* Check GetCursorFrameInfo behavior on a static cursor */
|
||||
unk1 = unk2 = unk3 = unk4 = 0xdead;
|
||||
h2 = pGetCursorFrameInfo(h1, &unk1, &unk2, &unk3, &unk4);
|
||||
ok(h1 == h2, "GetCursorFrameInfo() failed: (%p != %p).\n", h1, h2);
|
||||
ok(unk1 == 0xdead, "GetCursorFrameInfo() unexpected param 2 value (%d != 0xdead).\n", unk1);
|
||||
ok(unk2 == 0xdead, "GetCursorFrameInfo() unexpected param 3 value (%d != 0xdead).\n", unk2);
|
||||
ok(unk3 == 0, "GetCursorFrameInfo() unexpected param 4 value (0x%x != 0x0).\n", unk3);
|
||||
ok(unk4 == 1, "GetCursorFrameInfo() unexpected param 5 value (%d != 1).\n", unk4);
|
||||
|
||||
/* Clean up static cursor. */
|
||||
ret = DestroyCursor(h1);
|
||||
ok(ret, "DestroyCursor() failed.\n");
|
||||
|
||||
/* Creating a single-frame animated cursor. */
|
||||
empty_anicursor.frames[0].data.icon_info.idType = 2; /* type: cursor */
|
||||
empty_anicursor.frames[0].data.icon_info.idEntries[0].xHotspot = 3;
|
||||
empty_anicursor.frames[0].data.icon_info.idEntries[0].yHotspot = 3;
|
||||
h1 = CreateIconFromResource((PBYTE) &empty_anicursor, sizeof(empty_anicursor3), FALSE, 0x00030000);
|
||||
ok(h1 != NULL, "Create cursor failed.\n");
|
||||
|
||||
/* Check GetCursorFrameInfo behavior on a single-frame animated cursor */
|
||||
unk1 = unk2 = unk3 = unk4 = 0xdead;
|
||||
h2 = pGetCursorFrameInfo(h1, &unk1, (VOID*)0, &unk3, &unk4);
|
||||
ok(h1 == h2, "GetCursorFrameInfo() failed: (%p != %p).\n", h1, h2);
|
||||
ok(unk1 == 0xdead, "GetCursorFrameInfo() unexpected param 2 value (%d != 0xdead).\n", unk1);
|
||||
ok(unk2 == 0xdead, "GetCursorFrameInfo() unexpected param 3 value (%d != 0xdead).\n", unk2);
|
||||
ok(unk3 == 0x0, "GetCursorFrameInfo() unexpected param 4 value (0x%x != 0x0).\n", unk3);
|
||||
ok(unk4 == 1, "GetCursorFrameInfo() unexpected param 5 value (%d != 1).\n", unk4);
|
||||
|
||||
/* Clean up single-frame animated cursor. */
|
||||
ret = DestroyCursor(h1);
|
||||
ok(ret, "DestroyCursor() failed.\n");
|
||||
|
||||
/* Creating a multi-frame animated cursor. */
|
||||
empty_anicursor3.frames[0].data.icon_info.idType = 2; /* type: cursor */
|
||||
empty_anicursor3.frames[0].data.icon_info.idEntries[0].xHotspot = 3;
|
||||
empty_anicursor3.frames[0].data.icon_info.idEntries[0].yHotspot = 3;
|
||||
empty_anicursor3.frames[1].data.icon_info.idType = 2; /* type: cursor */
|
||||
empty_anicursor3.frames[1].data.icon_info.idEntries[0].xHotspot = 3;
|
||||
empty_anicursor3.frames[1].data.icon_info.idEntries[0].yHotspot = 3;
|
||||
empty_anicursor3.frames[2].data.icon_info.idType = 2; /* type: cursor */
|
||||
empty_anicursor3.frames[2].data.icon_info.idEntries[0].xHotspot = 3;
|
||||
empty_anicursor3.frames[2].data.icon_info.idEntries[0].yHotspot = 3;
|
||||
h1 = CreateIconFromResource((PBYTE) &empty_anicursor3, sizeof(empty_anicursor3), FALSE, 0x00030000);
|
||||
ok(h1 != NULL, "Create cursor failed.\n");
|
||||
|
||||
/* Check GetCursorFrameInfo behavior on a multi-frame animated cursor */
|
||||
unk1 = unk2 = unk3 = unk4 = 0xdead;
|
||||
h2 = pGetCursorFrameInfo(h1, &unk1, (VOID*)0, &unk3, &unk4);
|
||||
ok(h2 != 0, "GetCursorFrameInfo() failed: (%p != 0).\n", h2);
|
||||
ok(unk1 == 0xdead, "GetCursorFrameInfo() unexpected param 2 value (%d != 0xdead).\n", unk1);
|
||||
ok(unk2 == 0xdead, "GetCursorFrameInfo() unexpected param 3 value (%d != 0xdead).\n", unk2);
|
||||
ok(unk3 == 0xbeef, "GetCursorFrameInfo() unexpected param 4 value (0x%x != 0xbeef).\n", unk3);
|
||||
ok(unk4 == ~0 || broken(unk4 == 1) /*win2k*/, "GetCursorFrameInfo() unexpected param 5 value (%d != 1).\n", unk4);
|
||||
|
||||
/* Check GetCursorFrameInfo behavior on a multi-frame animated cursor */
|
||||
unk1 = unk2 = unk3 = unk4 = 0xdead;
|
||||
h2 = pGetCursorFrameInfo(h1, &unk1, (VOID*)1, &unk3, &unk4);
|
||||
ok(h2 == 0, "GetCursorFrameInfo() failed: (%p != 0).\n", h2);
|
||||
ok(unk1 == 0xdead, "GetCursorFrameInfo() unexpected param 2 value (%d != 0xdead).\n", unk1);
|
||||
ok(unk2 == 0xdead, "GetCursorFrameInfo() unexpected param 3 value (%d != 0xdead).\n", unk2);
|
||||
ok(unk3 == 0xdead || broken(unk3 == 0xbeef) /*win2k*/, "GetCursorFrameInfo() unexpected param 4 value (0x%x != 0xdead).\n", unk3);
|
||||
ok(unk4 == 0xdead || broken(unk4 == 1) /*win2k*/, "GetCursorFrameInfo() unexpected param 5 value (%d != 0xdead).\n", unk4);
|
||||
|
||||
/* Clean up multi-frame animated cursor. */
|
||||
ret = DestroyCursor(h1);
|
||||
ok(ret, "DestroyCursor() failed.\n");
|
||||
|
||||
}
|
||||
|
||||
static HICON create_test_icon(HDC hdc, int width, int height, int bpp,
|
||||
BOOL maskvalue, UINT32 *color, int colorSize)
|
||||
{
|
||||
|
@ -2062,6 +2322,7 @@ START_TEST(cursoricon)
|
|||
pGetCursorInfo = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetCursorInfo" );
|
||||
pGetIconInfoExA = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetIconInfoExA" );
|
||||
pGetIconInfoExW = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetIconInfoExW" );
|
||||
pGetCursorFrameInfo = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetCursorFrameInfo" );
|
||||
test_argc = winetest_get_mainargs(&test_argv);
|
||||
|
||||
if (test_argc >= 3)
|
||||
|
@ -2087,6 +2348,7 @@ START_TEST(cursoricon)
|
|||
test_CreateIcon();
|
||||
test_LoadImage();
|
||||
test_CreateIconFromResource();
|
||||
test_GetCursorFrameInfo();
|
||||
test_DrawIcon();
|
||||
test_DrawIconEx();
|
||||
test_DrawState();
|
||||
|
|
|
@ -272,7 +272,7 @@
|
|||
@ stdcall GetClipboardViewer()
|
||||
@ stdcall GetComboBoxInfo(long ptr)
|
||||
@ stdcall GetCursor()
|
||||
# @ stub GetCursorFrameInfo
|
||||
@ stdcall GetCursorFrameInfo(long long long ptr ptr)
|
||||
@ stdcall GetCursorInfo(ptr)
|
||||
@ stdcall GetCursorPos(ptr)
|
||||
@ stdcall GetDC(long)
|
||||
|
|
|
@ -4646,6 +4646,7 @@ WINUSERAPI BOOL WINAPI GetClipCursor(LPRECT);
|
|||
WINUSERAPI BOOL WINAPI GetComboBoxInfo(HWND,PCOMBOBOXINFO);
|
||||
WINUSERAPI HCURSOR WINAPI GetCursor(void);
|
||||
WINUSERAPI BOOL WINAPI GetCursorInfo(PCURSORINFO);
|
||||
WINUSERAPI HCURSOR WINAPI GetCursorFrameInfo(HCURSOR,DWORD,DWORD,DWORD*,DWORD*);
|
||||
WINUSERAPI BOOL WINAPI GetCursorPos(LPPOINT);
|
||||
WINUSERAPI HDC WINAPI GetDC(HWND);
|
||||
WINUSERAPI HDC WINAPI GetDCEx(HWND,HRGN,DWORD);
|
||||
|
|
Loading…
Reference in a new issue