user32: Add wrapper functions for manipulation of cursor/icon handles.

This commit is contained in:
Alexandre Julliard 2009-12-22 17:04:33 +01:00
parent 00e75f2b9e
commit 0280f058f9
2 changed files with 105 additions and 58 deletions

View File

@ -90,6 +90,29 @@ static HDC screen_dc;
static const WCHAR DISPLAYW[] = {'D','I','S','P','L','A','Y',0};
static HICON alloc_icon_handle( unsigned int size )
{
HGLOBAL16 handle = GlobalAlloc16( GMEM_MOVEABLE, size );
FarSetOwner16( handle, 0 );
return HICON_32( handle );
}
static CURSORICONINFO *get_icon_ptr( HICON handle )
{
return GlobalLock16( HICON_16(handle) );
}
static void release_icon_ptr( HICON handle, CURSORICONINFO *ptr )
{
GlobalUnlock16( HICON_16(handle) );
}
static int free_icon_handle( HICON handle )
{
return GlobalFree16( HICON_16(handle) );
}
/**********************************************************************
* ICONCACHE for cursors/icons loaded with LR_SHARED.
*
@ -449,10 +472,10 @@ BOOL get_icon_size( HICON handle, SIZE *size )
{
CURSORICONINFO *info;
if (!(info = GlobalLock16( HICON_16(handle) ))) return FALSE;
if (!(info = get_icon_ptr( handle ))) return FALSE;
size->cx = info->nWidth;
size->cy = info->nHeight;
GlobalUnlock16( HICON_16(handle) );
release_icon_ptr( handle, info );
return TRUE;
}
@ -679,7 +702,7 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
INT width, INT height,
UINT cFlag )
{
HGLOBAL16 hObj;
HICON hObj;
int sizeAnd, sizeXor;
HBITMAP hAndBits = 0, hXorBits = 0; /* error condition for later */
BITMAP bmpXor, bmpAnd;
@ -829,13 +852,11 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
sizeXor = bmpXor.bmHeight * bmpXor.bmWidthBytes;
sizeAnd = bmpAnd.bmHeight * bmpAnd.bmWidthBytes;
hObj = GlobalAlloc16( GMEM_MOVEABLE,
sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
hObj = alloc_icon_handle( sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
if (hObj)
{
CURSORICONINFO *info;
CURSORICONINFO *info = get_icon_ptr( hObj );
info = GlobalLock16( hObj );
info->ptHotSpot.x = hotspot.x;
info->ptHotSpot.y = hotspot.y;
info->nWidth = bmpXor.bmWidth;
@ -848,12 +869,12 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
GetBitmapBits( hAndBits, sizeAnd, info + 1 );
GetBitmapBits( hXorBits, sizeXor, (char *)(info + 1) + sizeAnd );
GlobalUnlock16( hObj );
release_icon_ptr( hObj, info );
}
DeleteObject( hAndBits );
DeleteObject( hXorBits );
return HICON_32(hObj);
return hObj;
}
@ -1449,20 +1470,19 @@ HICON WINAPI CreateIcon(
*/
HICON WINAPI CopyIcon( HICON hIcon )
{
char *ptrOld, *ptrNew;
CURSORICONINFO *ptrOld, *ptrNew;
int size;
HICON16 hOld = HICON_16(hIcon);
HICON16 hNew;
HICON hNew;
if (!(ptrOld = GlobalLock16( hOld ))) return 0;
if (!(ptrOld = get_icon_ptr( hIcon ))) return 0;
size = GlobalSize16( hOld );
hNew = GlobalAlloc16( GMEM_MOVEABLE, size );
FarSetOwner16( hNew, 0 );
ptrNew = GlobalLock16( hNew );
hNew = alloc_icon_handle( size );
ptrNew = get_icon_ptr( hNew );
memcpy( ptrNew, ptrOld, size );
GlobalUnlock16( hOld );
GlobalUnlock16( hNew );
return HICON_32(hNew);
release_icon_ptr( hIcon, ptrOld );
release_icon_ptr( hNew, ptrNew );
return hNew;
}
@ -1474,7 +1494,7 @@ BOOL WINAPI DestroyIcon( HICON hIcon )
TRACE_(icon)("%p\n", hIcon );
if (CURSORICON_DelSharedIcon( hIcon ) == -1)
GlobalFree16( HICON_16(hIcon) );
free_icon_handle( hIcon );
return TRUE;
}
@ -1574,8 +1594,12 @@ BOOL WINAPI DrawIcon( HDC hdc, INT x, INT y, HICON hIcon )
TRACE("%p, (%d,%d), %p\n", hdc, x, y, hIcon);
if (!(ptr = GlobalLock16(HICON_16(hIcon)))) return FALSE;
if (!(hMemDC = CreateCompatibleDC( hdc ))) return FALSE;
if (!(ptr = get_icon_ptr( hIcon ))) return FALSE;
if (!(hMemDC = CreateCompatibleDC( hdc )))
{
release_icon_ptr( hIcon, ptr );
return FALSE;
}
dibLength = ptr->nHeight * get_bitmap_width_bytes(
ptr->nWidth, ptr->bBitsPerPixel);
@ -1639,7 +1663,7 @@ BOOL WINAPI DrawIcon( HDC hdc, INT x, INT y, HICON hIcon )
DeleteDC( hMemDC );
if (hXorBits) DeleteObject( hXorBits );
if (hAndBits) DeleteObject( hAndBits );
GlobalUnlock16(HICON_16(hIcon));
release_icon_ptr( hIcon, ptr );
SetTextColor( hdc, oldFg );
SetBkColor( hdc, oldBg );
return TRUE;
@ -1665,8 +1689,10 @@ HCURSOR WINAPI DECLSPEC_HOTPATCH SetCursor( HCURSOR hCursor /* [in] Handle of cu
/* Change the cursor shape only if it is visible */
if (thread_info->cursor_count >= 0)
{
USER_Driver->pSetCursor(GlobalLock16(HCURSOR_16(hCursor)));
GlobalUnlock16(HCURSOR_16(hCursor));
CURSORICONINFO *info = get_icon_ptr( hCursor );
/* release before calling driver (FIXME) */
if (info) release_icon_ptr( hCursor, info );
USER_Driver->pSetCursor( info );
}
return hOldCursor;
}
@ -1684,8 +1710,10 @@ INT WINAPI DECLSPEC_HOTPATCH ShowCursor( BOOL bShow )
{
if (++thread_info->cursor_count == 0) /* Show it */
{
USER_Driver->pSetCursor(GlobalLock16(HCURSOR_16(thread_info->cursor)));
GlobalUnlock16(HCURSOR_16(thread_info->cursor));
CURSORICONINFO *info = get_icon_ptr( thread_info->cursor );
/* release before calling driver (FIXME) */
if (info) release_icon_ptr( thread_info->cursor, info );
USER_Driver->pSetCursor( info );
}
}
else
@ -1867,9 +1895,7 @@ BOOL WINAPI GetIconInfo(HICON hIcon, PICONINFO iconinfo)
CURSORICONINFO *ciconinfo;
INT height;
ciconinfo = GlobalLock16(HICON_16(hIcon));
if (!ciconinfo)
return FALSE;
if (!(ciconinfo = get_icon_ptr( hIcon ))) return FALSE;
TRACE("%p => %dx%d, %d bpp\n", hIcon,
ciconinfo->nWidth, ciconinfo->nHeight, ciconinfo->bBitsPerPixel);
@ -1906,8 +1932,7 @@ BOOL WINAPI GetIconInfo(HICON hIcon, PICONINFO iconinfo)
iconinfo->hbmMask = CreateBitmap ( ciconinfo->nWidth, height,
1, 1, ciconinfo + 1);
GlobalUnlock16(HICON_16(hIcon));
release_icon_ptr( hIcon, ciconinfo );
return TRUE;
}
@ -1919,7 +1944,7 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
{
DIBSECTION bmpXor;
BITMAP bmpAnd;
HICON16 hObj;
HICON hObj;
int xor_objsize = 0, sizeXor = 0, sizeAnd, planes, bpp;
TRACE("color %p, mask %p, hotspot %ux%u, fIcon %d\n",
@ -1948,13 +1973,10 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
sizeAnd = bmpAnd.bmHeight * get_bitmap_width_bytes(bmpAnd.bmWidth, 1);
hObj = GlobalAlloc16( GMEM_MOVEABLE,
sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
hObj = alloc_icon_handle( sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
if (hObj)
{
CURSORICONINFO *info;
info = GlobalLock16( hObj );
CURSORICONINFO *info = get_icon_ptr( hObj );
/* If we are creating an icon, the hotspot is unused */
if (iconinfo->fIcon)
@ -2063,9 +2085,9 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
dst_bits, &bminfo, DIB_RGB_COLORS );
}
}
GlobalUnlock16( hObj );
release_icon_ptr( hObj, info );
}
return HICON_32(hObj);
return hObj;
}
/******************************************************************************
@ -2104,8 +2126,12 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon,
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 );
if (!(ptr = GlobalLock16(HICON_16(hIcon)))) return FALSE;
if (!(hMemDC = CreateCompatibleDC( hdc ))) return FALSE;
if (!(ptr = get_icon_ptr( hIcon ))) return FALSE;
if (!(hMemDC = CreateCompatibleDC( hdc )))
{
release_icon_ptr( hIcon, ptr );
return FALSE;
}
if (istep)
FIXME_(icon)("Ignoring istep=%d\n", istep);
@ -2251,7 +2277,7 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon,
if (hMemDC) DeleteDC( hMemDC );
if (hDC_off) DeleteDC(hDC_off);
if (hB_off) DeleteObject(hB_off);
GlobalUnlock16(HICON_16(hIcon));
release_icon_ptr( hIcon, ptr );
return result;
}

View File

@ -251,7 +251,7 @@ static INT parse_format( LPCSTR format, WPRINTF_FORMAT *res )
/**********************************************************************
* Management of the 16-bit cursor/icon cache
* Management of the 16-bit cursors and icons
*/
struct cache_entry
@ -266,6 +266,28 @@ struct cache_entry
static struct list icon_cache = LIST_INIT( icon_cache );
static HICON16 alloc_icon_handle( unsigned int size )
{
HGLOBAL16 handle = GlobalAlloc16( GMEM_MOVEABLE, size );
FarSetOwner16( handle, 0 );
return handle;
}
static CURSORICONINFO *get_icon_ptr( HICON16 handle )
{
return GlobalLock16( handle );
}
static void release_icon_ptr( HICON16 handle, CURSORICONINFO *ptr )
{
GlobalUnlock16( handle );
}
static int free_icon_handle( HICON16 handle )
{
return GlobalFree16( handle );
}
static void add_shared_icon( HINSTANCE16 inst, HRSRC16 rsrc, HRSRC16 group, HICON16 icon )
{
struct cache_entry *cache = HeapAlloc( GetProcessHeap(), 0, sizeof(*cache) );
@ -313,7 +335,7 @@ static void free_module_icons( HINSTANCE16 inst )
{
if (cache->inst != inst) continue;
list_remove( &cache->entry );
GlobalFree16( cache->icon );
free_icon_handle( cache->icon );
HeapFree( GetProcessHeap(), 0, cache );
}
}
@ -1662,11 +1684,11 @@ INT16 WINAPI LookupIconIdFromDirectoryEx16( LPBYTE dir, BOOL16 bIcon,
*/
HICON16 WINAPI CopyIcon16( HINSTANCE16 hInstance, HICON16 hIcon )
{
CURSORICONINFO *info = GlobalLock16( hIcon );
CURSORICONINFO *info = get_icon_ptr( hIcon );
void *and_bits = info + 1;
void *xor_bits = (BYTE *)and_bits + info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
HGLOBAL16 ret = CreateCursorIconIndirect16( hInstance, info, and_bits, xor_bits );
GlobalUnlock16( hIcon );
release_icon_ptr( hIcon, info );
return ret;
}
@ -1676,11 +1698,11 @@ HICON16 WINAPI CopyIcon16( HINSTANCE16 hInstance, HICON16 hIcon )
*/
HCURSOR16 WINAPI CopyCursor16( HINSTANCE16 hInstance, HCURSOR16 hCursor )
{
CURSORICONINFO *info = GlobalLock16( hCursor );
CURSORICONINFO *info = get_icon_ptr( hCursor );
void *and_bits = info + 1;
void *xor_bits = (BYTE *)and_bits + info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
HGLOBAL16 ret = CreateCursorIconIndirect16( hInstance, info, and_bits, xor_bits );
GlobalUnlock16( hCursor );
release_icon_ptr( hCursor, info );
return ret;
}
@ -1921,8 +1943,8 @@ HGLOBAL16 WINAPI CreateCursorIconIndirect16( HINSTANCE16 hInstance,
LPCVOID lpANDbits,
LPCVOID lpXORbits )
{
HGLOBAL16 handle;
char *ptr;
HICON16 handle;
CURSORICONINFO *ptr;
int sizeAnd, sizeXor;
hInstance = GetExePtr( hInstance ); /* Make it a module handle */
@ -1930,15 +1952,14 @@ HGLOBAL16 WINAPI CreateCursorIconIndirect16( HINSTANCE16 hInstance,
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)))
if (!(handle = alloc_icon_handle( sizeof(CURSORICONINFO) + sizeXor + sizeAnd )))
return 0;
FarSetOwner16( handle, hInstance );
ptr = GlobalLock16( handle );
ptr = get_icon_ptr( handle );
memcpy( ptr, info, sizeof(*info) );
memcpy( ptr + sizeof(CURSORICONINFO), lpANDbits, sizeAnd );
memcpy( ptr + sizeof(CURSORICONINFO) + sizeAnd, lpXORbits, sizeXor );
GlobalUnlock16( handle );
memcpy( ptr + 1, lpANDbits, sizeAnd );
memcpy( (char *)(ptr + 1) + sizeAnd, lpXORbits, sizeXor );
release_icon_ptr( handle, ptr );
return handle;
}
@ -2335,7 +2356,7 @@ BOOL16 WINAPI DestroyIcon16(HICON16 hIcon)
count = release_shared_icon( hIcon );
if (count != -1) return !count;
/* assume non-shared */
GlobalFree16( hIcon );
free_icon_handle( hIcon );
return TRUE;
}
@ -2887,7 +2908,7 @@ WORD WINAPI DestroyIcon32( HGLOBAL16 handle, UINT16 flags )
/* Now assume non-shared cursor/icon */
retv = GlobalFree16( handle );
retv = free_icon_handle( handle );
return (flags & CID_RESOURCE)? retv : TRUE;
}