mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-01 19:26:16 +00:00
[USER32]
- There is no exported "CopyCursor", it's a macro. - There is no "NtUserCreateCursorIconHandle" function in win32k. Use correct functions to create a cursorIcon handle. - Bring in WINE's CreateIconIndirect [WIN32K] - Dereference CursorIcon Object in NtUserCallOneParam - Shared Icons need their bitmaps to be unowned svn path=/trunk/; revision=48034
This commit is contained in:
@@ -759,7 +759,6 @@
|
||||
; @ stdcall CharNextExW(long wstr long)
|
||||
; @ stdcall CharPrevExW(long wstr wstr long)
|
||||
; @ stub ClientThreadConnect
|
||||
@ stdcall CopyCursor(long) ; In msdn it is written, that function is available, but in win 2k3 r2 it is absent
|
||||
; @ stub EnumDisplayDeviceModesA ;(str long ptr long)
|
||||
; @ stub EnumDisplayDeviceModesW ;(wstr long ptr long)
|
||||
; @ stdcall GetMenuIndex(ptr ptr)
|
||||
|
||||
@@ -67,6 +67,25 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
};
|
||||
static CRITICAL_SECTION IconCrst = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
/***********************************************************************
|
||||
* CreateCursorIconHandle
|
||||
*
|
||||
* Creates a handle with everything in there
|
||||
*/
|
||||
static
|
||||
HICON
|
||||
CreateCursorIconHandle( PICONINFO IconInfo )
|
||||
{
|
||||
HICON hIcon = (HICON)NtUserCallOneParam(0, //FIXME ?
|
||||
ONEPARAM_ROUTINE_CREATECURICONHANDLE);
|
||||
if(!hIcon)
|
||||
return NULL;
|
||||
|
||||
NtUserSetCursorContents(hIcon, IconInfo);
|
||||
return hIcon;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* map_fileW
|
||||
@@ -563,7 +582,7 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
|
||||
IconInfo.hbmColor = color;
|
||||
IconInfo.hbmMask = mask;
|
||||
|
||||
return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
|
||||
return CreateCursorIconHandle(&IconInfo);
|
||||
}
|
||||
|
||||
|
||||
@@ -1386,55 +1405,120 @@ BOOL WINAPI GetIconInfo(HICON hIcon, PICONINFO iconinfo)
|
||||
return NtUserGetIconInfo(hIcon, iconinfo, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* copy an icon bitmap, even when it can't be selected into a DC */
|
||||
/* helper for CreateIconIndirect */
|
||||
static void stretch_blt_icon( HDC hdc_dst, int dst_x, int dst_y, int dst_width, int dst_height,
|
||||
HBITMAP src, int width, int height )
|
||||
{
|
||||
HDC hdc = CreateCompatibleDC( 0 );
|
||||
|
||||
if (!SelectObject( hdc, src )) /* do it the hard way */
|
||||
{
|
||||
BITMAPINFO *info;
|
||||
void *bits;
|
||||
|
||||
if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) return;
|
||||
info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
info->bmiHeader.biWidth = width;
|
||||
info->bmiHeader.biHeight = height;
|
||||
info->bmiHeader.biPlanes = GetDeviceCaps( hdc_dst, PLANES );
|
||||
info->bmiHeader.biBitCount = GetDeviceCaps( hdc_dst, BITSPIXEL );
|
||||
info->bmiHeader.biCompression = BI_RGB;
|
||||
info->bmiHeader.biSizeImage = height * get_dib_width_bytes( width, info->bmiHeader.biBitCount );
|
||||
info->bmiHeader.biXPelsPerMeter = 0;
|
||||
info->bmiHeader.biYPelsPerMeter = 0;
|
||||
info->bmiHeader.biClrUsed = 0;
|
||||
info->bmiHeader.biClrImportant = 0;
|
||||
bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage );
|
||||
if (bits && GetDIBits( hdc, src, 0, height, bits, info, DIB_RGB_COLORS ))
|
||||
StretchDIBits( hdc_dst, dst_x, dst_y, dst_width, dst_height,
|
||||
0, 0, width, height, bits, info, DIB_RGB_COLORS, SRCCOPY );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, bits );
|
||||
HeapFree( GetProcessHeap(), 0, info );
|
||||
}
|
||||
else StretchBlt( hdc_dst, dst_x, dst_y, dst_width, dst_height, hdc, 0, 0, width, height, SRCCOPY );
|
||||
|
||||
DeleteDC( hdc );
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* CreateIconIndirect (USER32.@)
|
||||
*/
|
||||
HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
|
||||
{
|
||||
BITMAP ColorBitmap;
|
||||
BITMAP MaskBitmap;
|
||||
ICONINFO safeIconInfo;
|
||||
BITMAP bmpXor, bmpAnd;
|
||||
HBITMAP color = 0, mask;
|
||||
int width, height;
|
||||
HDC hdc;
|
||||
ICONINFO iinfo;
|
||||
|
||||
if(!iconinfo)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return (HICON)0;
|
||||
}
|
||||
TRACE("color %p, mask %p, hotspot %ux%u, fIcon %d\n",
|
||||
iconinfo->hbmColor, iconinfo->hbmMask,
|
||||
iconinfo->xHotspot, iconinfo->yHotspot, iconinfo->fIcon);
|
||||
|
||||
safeIconInfo = *iconinfo;
|
||||
if (!iconinfo->hbmMask) return 0;
|
||||
|
||||
if(!GetObjectW(safeIconInfo.hbmMask, sizeof(BITMAP), &MaskBitmap))
|
||||
{
|
||||
return (HICON)0;
|
||||
}
|
||||
GetObjectW( iconinfo->hbmMask, sizeof(bmpAnd), &bmpAnd );
|
||||
TRACE("mask: width %d, height %d, width bytes %d, planes %u, bpp %u\n",
|
||||
bmpAnd.bmWidth, bmpAnd.bmHeight, bmpAnd.bmWidthBytes,
|
||||
bmpAnd.bmPlanes, bmpAnd.bmBitsPixel);
|
||||
|
||||
/* Try to get color bitmap */
|
||||
if (GetObjectW(safeIconInfo.hbmColor, sizeof(BITMAP), &ColorBitmap))
|
||||
{
|
||||
/* Compare size of color and mask bitmap*/
|
||||
if (ColorBitmap.bmWidth != MaskBitmap.bmWidth ||
|
||||
ColorBitmap.bmHeight != MaskBitmap.bmHeight)
|
||||
{
|
||||
ERR("Color and mask size are different!");
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return (HICON)0;
|
||||
}
|
||||
/* Test if they are inverted */
|
||||
if(ColorBitmap.bmBitsPixel == 1)
|
||||
{
|
||||
if(MaskBitmap.bmBitsPixel != 1)
|
||||
{
|
||||
safeIconInfo.hbmMask = iconinfo->hbmColor;
|
||||
safeIconInfo.hbmColor = iconinfo->hbmMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wine tests say so */
|
||||
safeIconInfo.hbmColor = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (HICON)NtUserCreateCursorIconHandle(&safeIconInfo, TRUE);
|
||||
if (iconinfo->hbmColor)
|
||||
{
|
||||
GetObjectW( iconinfo->hbmColor, sizeof(bmpXor), &bmpXor );
|
||||
TRACE("color: width %d, height %d, width bytes %d, planes %u, bpp %u\n",
|
||||
bmpXor.bmWidth, bmpXor.bmHeight, bmpXor.bmWidthBytes,
|
||||
bmpXor.bmPlanes, bmpXor.bmBitsPixel);
|
||||
|
||||
width = bmpXor.bmWidth;
|
||||
height = bmpXor.bmHeight;
|
||||
if (bmpXor.bmPlanes * bmpXor.bmBitsPixel != 1)
|
||||
{
|
||||
color = CreateCompatibleBitmap( screen_dc, width, height );
|
||||
mask = CreateBitmap( width, height, 1, 1, NULL );
|
||||
}
|
||||
else mask = CreateBitmap( width, height * 2, 1, 1, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
width = bmpAnd.bmWidth;
|
||||
height = bmpAnd.bmHeight;
|
||||
mask = CreateBitmap( width, height, 1, 1, NULL );
|
||||
}
|
||||
|
||||
hdc = CreateCompatibleDC( 0 );
|
||||
SelectObject( hdc, mask );
|
||||
stretch_blt_icon( hdc, 0, 0, width, height, iconinfo->hbmMask, bmpAnd.bmWidth, bmpAnd.bmHeight );
|
||||
|
||||
if (color)
|
||||
{
|
||||
SelectObject( hdc, color );
|
||||
stretch_blt_icon( hdc, 0, 0, width, height, iconinfo->hbmColor, width, height );
|
||||
}
|
||||
else if (iconinfo->hbmColor)
|
||||
{
|
||||
stretch_blt_icon( hdc, 0, height, width, height, iconinfo->hbmColor, width, height );
|
||||
}
|
||||
else height /= 2;
|
||||
|
||||
DeleteDC( hdc );
|
||||
|
||||
iinfo.hbmColor = color ;
|
||||
iinfo.hbmMask = mask ;
|
||||
iinfo.fIcon = iconinfo->fIcon;
|
||||
if (iinfo.fIcon)
|
||||
{
|
||||
iinfo.xHotspot = width / 2;
|
||||
iinfo.yHotspot = height / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
iinfo.xHotspot = iconinfo->xHotspot;
|
||||
iinfo.yHotspot = iconinfo->yHotspot;
|
||||
}
|
||||
|
||||
return CreateCursorIconHandle(&iinfo);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -2047,23 +2131,6 @@ GetCursorPos(LPPOINT lpPoint)
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef CopyCursor
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HCURSOR
|
||||
WINAPI
|
||||
CopyCursor(HCURSOR pcur)
|
||||
{
|
||||
ICONINFO IconInfo;
|
||||
|
||||
if(GetIconInfo((HANDLE)pcur, &IconInfo))
|
||||
{
|
||||
return (HCURSOR)NtUserCreateCursorIconHandle(&IconInfo, FALSE);
|
||||
}
|
||||
return (HCURSOR)0;
|
||||
}
|
||||
|
||||
/* INTERNAL ******************************************************************/
|
||||
|
||||
/* This callback routine is called directly after switching to gui mode */
|
||||
|
||||
@@ -1030,11 +1030,13 @@ NtUserSetCursorContents(
|
||||
}
|
||||
|
||||
/* Delete old bitmaps */
|
||||
if (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor)
|
||||
if ((CurIcon->IconInfo.hbmColor)
|
||||
&& (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor))
|
||||
{
|
||||
GreDeleteObject(CurIcon->IconInfo.hbmColor);
|
||||
}
|
||||
if (CurIcon->IconInfo.hbmMask != IconInfo.hbmMask)
|
||||
if ((CurIcon->IconInfo.hbmMask)
|
||||
&& (CurIcon->IconInfo.hbmMask != IconInfo.hbmMask))
|
||||
{
|
||||
GreDeleteObject(CurIcon->IconInfo.hbmMask);
|
||||
}
|
||||
@@ -1226,6 +1228,15 @@ NtUserSetCursorIconData(
|
||||
}
|
||||
|
||||
done:
|
||||
if(Ret)
|
||||
{
|
||||
/* This icon is shared now */
|
||||
GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL);
|
||||
if(CurIcon->IconInfo.hbmColor)
|
||||
{
|
||||
GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmColor, NULL);
|
||||
}
|
||||
}
|
||||
UserDereferenceObject(CurIcon);
|
||||
RETURN(Ret);
|
||||
|
||||
|
||||
@@ -195,6 +195,7 @@ NtUserCallOneParam(
|
||||
case ONEPARAM_ROUTINE_CREATECURICONHANDLE:
|
||||
{
|
||||
PCURICON_OBJECT CurIcon;
|
||||
DWORD_PTR Result ;
|
||||
|
||||
if (!(CurIcon = IntCreateCurIconHandle()))
|
||||
{
|
||||
@@ -202,7 +203,9 @@ NtUserCallOneParam(
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
RETURN((DWORD_PTR)CurIcon->Self);
|
||||
Result = (DWORD_PTR)CurIcon->Self;
|
||||
UserDereferenceObject(CurIcon);
|
||||
RETURN(Result);
|
||||
}
|
||||
|
||||
case ONEPARAM_ROUTINE_GETCURSORPOSITION:
|
||||
|
||||
Reference in New Issue
Block a user