Check for failed allocations. Spotted by Martin Bealby.
[reactos.git] / reactos / lib / user32 / windows / icon.c
index 6dc7a75..28d36ad 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: icon.c,v 1.5 2003/06/03 22:25:37 ekohl Exp $
+/* $Id$
  *
  * PROJECT:         ReactOS user32.dll
  * FILE:            lib/user32/windows/icon.c
 
 /* INCLUDES ******************************************************************/
 
-#include <windows.h>
 #include <user32.h>
-#include <string.h>
-#include <stdlib.h>
+#define NDEBUG
 #include <debug.h>
 
+
 /* FUNCTIONS *****************************************************************/
 
 HICON
-ICON_CreateIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired)
+ICON_CreateIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot)
 {
-  HANDLE hXORBitmap;
-  HANDLE hANDBitmap;
-  BITMAPINFO* bwBIH;
-  ICONINFO IconInfo;
-  HICON hIcon;
-
-  //load the XOR bitmap
-  hXORBitmap = CreateDIBitmap(hDC, &IconImage->icHeader, CBM_INIT,
-                              ImageData, (BITMAPINFO*)IconImage, DIB_RGB_COLORS);
-
-  //make ImageData point to the start of the AND image data
-  ImageData = ((PBYTE)ImageData) + (((IconImage->icHeader.biWidth * 
-                                      IconImage->icHeader.biBitCount + 31) & ~31) >> 3) * 
+   BYTE BitmapInfoBuffer[sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD)];
+   BITMAPINFO *bwBIH = (BITMAPINFO *)BitmapInfoBuffer;
+   ICONINFO IconInfo;
+
+   IconInfo.fIcon = TRUE;
+   IconInfo.xHotspot = xHotspot;
+   IconInfo.yHotspot = yHotspot;
+
+   /* Load the XOR bitmap */
+   IconInfo.hbmColor = CreateDIBitmap(hDC, &IconImage->icHeader, CBM_INIT,
+                                      ImageData, (BITMAPINFO*)IconImage,
+                                      DIB_RGB_COLORS);
+
+   /* Make ImageData point to the start of the AND image data. */
+   ImageData = ((PBYTE)ImageData) + (((IconImage->icHeader.biWidth *
+                                      IconImage->icHeader.biBitCount + 31) & ~31) >> 3) *
                                       (IconImage->icHeader.biHeight );
 
-  //create a BITMAPINFO header for the monocrome part of the icon
-  bwBIH = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof (BITMAPINFOHEADER)+2*sizeof(RGBQUAD));
-
-  bwBIH->bmiHeader.biBitCount = 1;
-  bwBIH->bmiHeader.biWidth = IconImage->icHeader.biWidth;
-  bwBIH->bmiHeader.biHeight = IconImage->icHeader.biHeight;
-  bwBIH->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-  bwBIH->bmiHeader.biPlanes = 1;
-  bwBIH->bmiHeader.biSizeImage = (((IconImage->icHeader.biWidth * 1 + 31) & ~31) >> 3) * 
-                                    (IconImage->icHeader.biHeight );
-  bwBIH->bmiHeader.biCompression = BI_RGB;
-  bwBIH->bmiHeader.biClrImportant = 0;
-  bwBIH->bmiHeader.biClrUsed = 0;
-  bwBIH->bmiHeader.biXPelsPerMeter = 0;
-  bwBIH->bmiHeader.biYPelsPerMeter = 0;
-
-  bwBIH->bmiColors[0].rgbBlue = 0;
-  bwBIH->bmiColors[0].rgbGreen = 0;
-  bwBIH->bmiColors[0].rgbRed = 0;
-  bwBIH->bmiColors[0].rgbReserved = 0;
-
-  bwBIH->bmiColors[1].rgbBlue = 0xff;
-  bwBIH->bmiColors[1].rgbGreen = 0xff;
-  bwBIH->bmiColors[1].rgbRed = 0xff;
-  bwBIH->bmiColors[1].rgbReserved = 0;
-
-  //load the AND bitmap
-  hANDBitmap = CreateDIBitmap(hDC, &bwBIH->bmiHeader, CBM_INIT,
-                              ImageData, bwBIH, DIB_RGB_COLORS);
-
-  RtlFreeHeap(RtlGetProcessHeap(), 0, bwBIH);
-
-  IconInfo.fIcon = TRUE;
-  IconInfo.xHotspot = cxDesired/2;
-  IconInfo.yHotspot = cyDesired/2;
-  IconInfo.hbmColor = hXORBitmap;
-  IconInfo.hbmMask = hANDBitmap;
-
-  //Create the icon based on everything we have so far
-  hIcon = CreateIconIndirect(&IconInfo);
-
-  //clean up
-  DeleteObject(hXORBitmap);
-  DeleteObject(hANDBitmap);
+   /* Create a BITMAPINFO header for the monocrome part of the icon. */
+   bwBIH->bmiHeader.biBitCount = 1;
+   bwBIH->bmiHeader.biWidth = IconImage->icHeader.biWidth;
+   bwBIH->bmiHeader.biHeight = IconImage->icHeader.biHeight;
+   bwBIH->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+   bwBIH->bmiHeader.biPlanes = 1;
+   bwBIH->bmiHeader.biSizeImage = 0;
+   bwBIH->bmiHeader.biCompression = BI_RGB;
+   bwBIH->bmiHeader.biClrImportant = 0;
+   bwBIH->bmiHeader.biClrUsed = 0;
+   bwBIH->bmiHeader.biXPelsPerMeter = 0;
+   bwBIH->bmiHeader.biYPelsPerMeter = 0;
+
+   bwBIH->bmiColors[0].rgbBlue = 0;
+   bwBIH->bmiColors[0].rgbGreen = 0;
+   bwBIH->bmiColors[0].rgbRed = 0;
+   bwBIH->bmiColors[0].rgbReserved = 0;
+
+   bwBIH->bmiColors[1].rgbBlue = 0xff;
+   bwBIH->bmiColors[1].rgbGreen = 0xff;
+   bwBIH->bmiColors[1].rgbRed = 0xff;
+   bwBIH->bmiColors[1].rgbReserved = 0;
+
+   /* Load the AND bitmap. */
+   IconInfo.hbmMask = CreateDIBitmap(hDC, &bwBIH->bmiHeader, 0,
+                                     ImageData, bwBIH, DIB_RGB_COLORS);
+
+   SetDIBits(hDC, IconInfo.hbmMask, 0, IconImage->icHeader.biHeight,
+             ImageData, bwBIH, DIB_RGB_COLORS);
+
+   /* Create the icon based on everything we have so far */
+   return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
+}
 
-  return hIcon;
+HICON
+ICON_CreateCursorFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot)
+{
+   /* FIXME - color cursors */
+   BYTE BitmapInfoBuffer[sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD)];
+   BITMAPINFO *bwBIH = (BITMAPINFO *)BitmapInfoBuffer;
+   ICONINFO IconInfo;
+   PVOID XORImageData = ImageData;
+
+   IconInfo.fIcon = FALSE;
+   IconInfo.xHotspot = xHotspot;
+   IconInfo.yHotspot = yHotspot;
+
+   /* Create a BITMAPINFO header for the monocrome part of the icon */
+   bwBIH->bmiHeader.biBitCount = 1;
+   bwBIH->bmiHeader.biWidth = IconImage->icHeader.biWidth;
+   bwBIH->bmiHeader.biHeight = IconImage->icHeader.biHeight;
+   bwBIH->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+   bwBIH->bmiHeader.biPlanes = 1;
+   bwBIH->bmiHeader.biSizeImage = 0;
+   bwBIH->bmiHeader.biCompression = BI_RGB;
+   bwBIH->bmiHeader.biClrImportant = 0;
+   bwBIH->bmiHeader.biClrUsed = 0;
+   bwBIH->bmiHeader.biXPelsPerMeter = 0;
+   bwBIH->bmiHeader.biYPelsPerMeter = 0;
+
+   bwBIH->bmiColors[0].rgbBlue = 0;
+   bwBIH->bmiColors[0].rgbGreen = 0;
+   bwBIH->bmiColors[0].rgbRed = 0;
+   bwBIH->bmiColors[0].rgbReserved = 0;
+
+   bwBIH->bmiColors[1].rgbBlue = 0xff;
+   bwBIH->bmiColors[1].rgbGreen = 0xff;
+   bwBIH->bmiColors[1].rgbRed = 0xff;
+   bwBIH->bmiColors[1].rgbReserved = 0;
+
+   /* Load the AND bitmap */
+   IconInfo.hbmMask = CreateDIBitmap(hDC, &bwBIH->bmiHeader, 0,
+                                     XORImageData, bwBIH, DIB_RGB_COLORS);
+   if (IconInfo.hbmMask)
+   {
+      SetDIBits(hDC, IconInfo.hbmMask, 0, IconImage->icHeader.biHeight,
+                XORImageData, bwBIH, DIB_RGB_COLORS);
+   }
+
+   IconInfo.hbmColor = (HBITMAP)0;
+
+   /* Create the icon based on everything we have so far */
+   return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
 }
 
+
+/*
+ * @implemented
+ */
 HICON
 STDCALL
 CopyIcon(
   HICON hIcon)
 {
   ICONINFO IconInfo;
-  GetIconInfo(hIcon, &IconInfo);
-  return CreateIconIndirect(&IconInfo);
+
+  if(NtUserGetCursorIconInfo((HANDLE)hIcon, &IconInfo))
+  {
+    return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
+  }
+  return (HICON)0;
 }
 
+
+/*
+ * @implemented
+ */
 HICON
 STDCALL
 CreateIcon(
@@ -120,38 +171,54 @@ CreateIcon(
   int nHeight,
   BYTE cPlanes,
   BYTE cBitsPixel,
-  CONST BYTE *lpbANDbits,
-  CONST BYTE *lpbXORbits)
+  CONST BYTE *ANDbits,
+  CONST BYTE *XORbits)
 {
-  DPRINT("hInstance not used in this implementation\n");
-  return W32kCreateIcon(TRUE,
-                        nWidth,
-                        nHeight,
-                        cPlanes,
-                        cBitsPixel,
-                        nWidth/2,
-                        nHeight/2,
-                        lpbANDbits,
-                        lpbXORbits);
+  ICONINFO IconInfo;
+
+  IconInfo.fIcon = TRUE;
+  IconInfo.xHotspot = nWidth / 2;
+  IconInfo.yHotspot = nHeight / 2;
+  IconInfo.hbmMask = CreateBitmap(nWidth, nHeight, 1, 1, ANDbits);
+  if(!IconInfo.hbmMask)
+  {
+    return (HICON)0;
+  }
+  IconInfo.hbmColor = CreateBitmap(nWidth, nHeight, cPlanes, cBitsPixel, XORbits);
+  if(!IconInfo.hbmColor)
+  {
+    DeleteObject(IconInfo.hbmMask);
+    return (HICON)0;
+  }
+
+  return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
 }
 
+
+/*
+ * @implemented
+ */
 HICON
 STDCALL
 CreateIconFromResource(
   PBYTE presbits,
   DWORD dwResSize,
-  WINBOOL fIcon,
+  BOOL fIcon,
   DWORD dwVer)
 {
-  return CreateIconFromResourceEx( presbits, dwResSize, fIcon, dwVer, 0,0,0);
+  return CreateIconFromResourceEx(presbits, dwResSize, fIcon, dwVer, 0, 0, 0);
 }
 
+
+/*
+ * @implemented
+ */
 HICON
 STDCALL
 CreateIconFromResourceEx(
   PBYTE pbIconBits,
   DWORD cbIconBits,
-  WINBOOL fIcon,
+  BOOL fIcon,
   DWORD dwVersion,
   int cxDesired,
   int cyDesired,
@@ -163,76 +230,135 @@ CreateIconFromResourceEx(
   ULONG ColourCount;
   PVOID Data;
   HDC hScreenDc;
+  WORD wXHotspot;
+  WORD wYHotspot;
 
-  DPRINT("fIcon, dwVersion, cxDesired, cyDesired are all ignored in this implementation!\n");
+  /*
+    FIXME - does win support LR_SHARED? According to msdn it does but we don't
+            have useful information to identify the icon
+  if (uFlags & LR_SHARED)
+  {
+    DbgPrint("FIXME: need LR_SHARED support in CreateIconFromResourceEx()\n");
+  }
+  */
 
-  //get an safe copy of the icon data
-  SafeIconImage = RtlAllocateHeap(RtlGetProcessHeap(), 0, cbIconBits);
+  DPRINT("dwVersion, cxDesired, cyDesired are all ignored in this implementation!\n");
+
+  if (! fIcon)
+    {
+      wXHotspot = (WORD)*pbIconBits;
+      pbIconBits+=2;
+      wYHotspot = (WORD)*pbIconBits;
+      pbIconBits+=2;
+      cbIconBits-=4;
+    }
+  else
+    {
+      wXHotspot = cxDesired / 2;
+      wYHotspot = cyDesired / 2;
+    }
+
+  /* get an safe copy of the icon data */
+  SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, cbIconBits);
+  if (SafeIconImage == NULL)
+    {
+      return NULL;
+    }
   memcpy(SafeIconImage, pbIconBits, cbIconBits);
 
-  //take into acount the origonal hight was for both the AND and XOR images
-  SafeIconImage->icHeader.biHeight /= 2;
+  /* take into acount the origonal height was for both the AND and XOR images */
+  if(fIcon)
+    SafeIconImage->icHeader.biHeight /= 2;
 
   if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))
-  {
+    {
       BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)SafeIconImage;
       ColourCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
       HeaderSize = sizeof(BITMAPCOREHEADER) + ColourCount * sizeof(RGBTRIPLE);
-  }
+    }
   else
-  {
-      ColourCount = (SafeIconImage->icHeader.biBitCount <= 8) ? 
+    {
+      ColourCount = (SafeIconImage->icHeader.biBitCount <= 8) ?
                        (1 << SafeIconImage->icHeader.biBitCount) : 0;
       HeaderSize = sizeof(BITMAPINFOHEADER) + ColourCount * sizeof(RGBQUAD);
-  }
+    }
 
-  //make data point to the start of the XOR image data
+  /* make data point to the start of the XOR image data */
   Data = (PBYTE)SafeIconImage + HeaderSize;
 
-  //get a handle to the screen dc, the icon we create is going to be compatable with this
-  hScreenDc = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
+  /* get a handle to the screen dc, the icon we create is going to be compatable with this */
+  hScreenDc = CreateCompatibleDC(NULL);
   if (hScreenDc == NULL)
-  {
-     RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage);
-     return(NULL);
-  }
+    {
+      RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
+      return(NULL);
+    }
+
+  if(fIcon)
+    hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired, wXHotspot, wYHotspot);
+  else
+    hIcon = ICON_CreateCursorFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired, wXHotspot, wYHotspot);
+  RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
+  DeleteDC(hScreenDc);
 
-  hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired);
-  RtlFreeHeap(RtlGetProcessHeap(), 0, SafeIconImage);
   return hIcon;
 }
 
+
+/*
+ * @implemented
+ */
 HICON
 STDCALL
-CreateIconIndirect(
-  PICONINFO piconinfo)
+CreateIconIndirect(PICONINFO IconInfo)
 {
-  BITMAP bmMask;
-  BITMAP bmColor;
-
-  W32kGetObject( piconinfo->hbmMask, sizeof(BITMAP), &bmMask );
-  W32kGetObject( piconinfo->hbmColor, sizeof(BITMAP), &bmColor );
-
-  return W32kCreateIcon(piconinfo->fIcon,
-                       bmColor.bmWidth,
-                       bmColor.bmHeight,
-                       bmColor.bmPlanes,
-                       bmColor.bmBitsPixel,
-                       piconinfo->xHotspot,
-                       piconinfo->yHotspot,
-                       bmMask.bmBits,
-                       bmColor.bmBits);
+  BITMAP ColorBitmap;
+  BITMAP MaskBitmap;
+
+  if(!IconInfo)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return (HICON)0;
+  }
+
+  if(!GetObjectW(IconInfo->hbmMask, sizeof(BITMAP), &MaskBitmap))
+  {
+    return (HICON)0;
+  }
+  /* FIXME - does there really *have* to be a color bitmap? monochrome cursors don't have one */
+  if(IconInfo->hbmColor && !GetObjectW(IconInfo->hbmColor, sizeof(BITMAP), &ColorBitmap))
+  {
+    return (HICON)0;
+  }
+
+  /* FIXME - i doubt this is right (monochrome cursors */
+  /*if(ColorBitmap.bmWidth != MaskBitmap.bmWidth ||
+     ColorBitmap.bmHeight != MaskBitmap.bmWidth)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return (HICON)0;
+  }*/
+
+  return (HICON)NtUserCreateCursorIconHandle(IconInfo, TRUE);
 }
 
-WINBOOL
+
+/*
+ * @implemented
+ */
+BOOL
 STDCALL
 DestroyIcon(
   HICON hIcon)
 {
-  return W32kDeleteObject(hIcon);
+  return (BOOL)NtUserDestroyCursorIcon((HANDLE)hIcon, 0);
 }
 
-WINBOOL
+
+/*
+ * @implemented
+ */
+BOOL
 STDCALL
 DrawIcon(
   HDC hDC,
@@ -240,11 +366,13 @@ DrawIcon(
   int Y,
   HICON hIcon)
 {
-  return DrawIconEx (hDC, X, Y, hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
+  return DrawIconEx(hDC, X, Y, hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_DEFAULTSIZE);
 }
 
-/* Ported from WINE20030408 */
-WINBOOL
+/*
+ * @implemented
+ */
+BOOL
 STDCALL
 DrawIconEx(
   HDC hdc,
@@ -257,148 +385,29 @@ DrawIconEx(
   HBRUSH hbrFlickerFreeDraw,
   UINT diFlags)
 {
-    ICONINFO IconInfo;
-    BITMAP XORBitmap;
-    HDC hDC_off = 0, hMemDC;
-    BOOL result = FALSE, DoOffscreen;
-    HBITMAP hB_off = 0, hOld = 0;
-
-    if (!GetIconInfo(hIcon, &IconInfo))
-      return FALSE;
-
-    W32kGetObject(IconInfo.hbmColor, sizeof(BITMAP), &XORBitmap);
-
-    DPRINT("(hdc=%p,pos=%d.%d,hicon=%p,extend=%d.%d,istep=%d,br=%p,flags=0x%08x)\n",
-                 hdc,xLeft,yTop,hIcon,cxWidth,cyWidth,istepIfAniCur,hbrFlickerFreeDraw,diFlags );
-
-    hMemDC = CreateCompatibleDC (hdc);
-    if (diFlags & DI_COMPAT)
-        DPRINT("Ignoring flag DI_COMPAT\n");
-
-    if (!diFlags)
-    {
-         diFlags = DI_NORMAL;
-    }
-
-    // Calculate the size of the destination image.
-    if (cxWidth == 0)
-    {
-      if (diFlags & DI_DEFAULTSIZE)
-            cxWidth = GetSystemMetrics (SM_CXICON);
-      else
-            cxWidth = XORBitmap.bmWidth;
-    }
-    if (cyWidth == 0)
-    {
-      if (diFlags & DI_DEFAULTSIZE)
-        cyWidth = GetSystemMetrics (SM_CYICON);
-      else
-           cyWidth = XORBitmap.bmHeight;
-    }
-
-    DoOffscreen = (GetObjectType( hbrFlickerFreeDraw ) == OBJ_BRUSH);
-
-    if (DoOffscreen)
-    {
-      RECT r;
-
-      r.left = 0;
-      r.top = 0;
-      r.right = cxWidth;
-      r.bottom = cxWidth;
-
-      DbgPrint("in DrawIconEx calling: CreateCompatibleDC\n");
-      hDC_off = CreateCompatibleDC(hdc);
-
-      DbgPrint("in DrawIconEx calling: CreateCompatibleBitmap\n");
-      hB_off = CreateCompatibleBitmap(hdc, cxWidth, cyWidth);
-      if (hDC_off && hB_off)
-      {
-        DbgPrint("in DrawIconEx calling: SelectObject\n");
-        hOld = SelectObject(hDC_off, hB_off);
-
-        DbgPrint("in DrawIconEx calling: FillRect\n");
-        FillRect(hDC_off, &r, hbrFlickerFreeDraw);
-      }
-    }
-
-    if (hMemDC && (!DoOffscreen || (hDC_off && hB_off)))
-    {
-      COLORREF  oldFg, oldBg;
-      INT     nStretchMode;
-
-      nStretchMode = SetStretchBltMode (hdc, STRETCH_DELETESCANS);
-
-      oldFg = SetTextColor( hdc, RGB(0,0,0) );
-
-      oldBg = SetBkColor( hdc, RGB(255,255,255) );
-
-      if (IconInfo.hbmColor && IconInfo.hbmMask)
-      {
-        HBITMAP hBitTemp = SelectObject( hMemDC, IconInfo.hbmMask );
-        if (diFlags & DI_MASK)
-        {
-          if (DoOffscreen)
-            StretchBlt (hDC_off, 0, 0, cxWidth, cyWidth,
-               hMemDC, 0, 0, XORBitmap.bmWidth, XORBitmap.bmHeight, SRCAND);
-          else
-            StretchBlt (hdc, xLeft, yTop, cxWidth, cyWidth,
-                 hMemDC, 0, 0, XORBitmap.bmWidth, XORBitmap.bmHeight, SRCAND);
-        }
-        SelectObject( hMemDC, IconInfo.hbmColor );
-        if (diFlags & DI_IMAGE)
-        {
-          if (DoOffscreen)
-            StretchBlt (hDC_off, 0, 0, cxWidth, cyWidth,
-               hMemDC, 0, 0, XORBitmap.bmWidth, XORBitmap.bmHeight, SRCPAINT);
-          else
-            StretchBlt (hdc, xLeft, yTop, cxWidth, cyWidth,
-              hMemDC, 0, 0, XORBitmap.bmWidth, XORBitmap.bmHeight, SRCPAINT);
-        }
-        SelectObject( hMemDC, hBitTemp );
-        result = TRUE;
-      }
-
-      SetTextColor( hdc, oldFg );
-      SetBkColor( hdc, oldBg );
-      if (IconInfo.hbmColor)
-        DeleteObject( IconInfo.hbmColor );
-
-      if (IconInfo.hbmMask) 
-        DeleteObject( IconInfo.hbmMask );
-
-      SetStretchBltMode (hdc, nStretchMode);
-
-      if (DoOffscreen)
-      {
-        BitBlt(hdc, xLeft, yTop, cxWidth, cyWidth, hDC_off, 0, 0, SRCCOPY);
-        SelectObject(hDC_off, hOld);
-      }
-    }
-
-    if (hMemDC)
-      DeleteDC( hMemDC );
-    if (hDC_off)
-      DeleteDC(hDC_off);
-    if (hB_off)
-      DeleteObject(hB_off);
-    return result;
+  return (BOOL)NtUserDrawIconEx(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth,
+                                   istepIfAniCur, hbrFlickerFreeDraw, diFlags,
+                                   0, 0);
 }
 
-WINBOOL
+
+/*
+ * @implemented
+ */
+BOOL
 STDCALL
 GetIconInfo(
   HICON hIcon,
-  PICONINFO piconinfo)
+  PICONINFO IconInfo)
 {
-  return NtUserGetIconInfo(hIcon,
-                           &piconinfo->fIcon,
-                           &piconinfo->xHotspot,
-                           &piconinfo->yHotspot,
-                           &piconinfo->hbmMask,
-                           &piconinfo->hbmColor);
+  /* FIXME - copy bitmaps */
+  return (BOOL)NtUserGetCursorIconInfo((HANDLE)hIcon, IconInfo);
 }
 
+
+/*
+ * @implemented
+ */
 HICON
 STDCALL
 LoadIconA(
@@ -408,6 +417,10 @@ LoadIconA(
   return(LoadImageA(hInstance, lpIconName, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE));
 }
 
+
+/*
+ * @implemented
+ */
 HICON
 STDCALL
 LoadIconW(
@@ -417,11 +430,15 @@ LoadIconW(
   return(LoadImageW(hInstance, lpIconName, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE));
 }
 
+
+/*
+ * @implemented
+ */
 int
 STDCALL
 LookupIconIdFromDirectory(
   PBYTE presbits,
-  WINBOOL fIcon)
+  BOOL fIcon)
 {
     return LookupIconIdFromDirectoryEx( presbits, fIcon,
           fIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR),
@@ -429,11 +446,11 @@ LookupIconIdFromDirectory(
 }
 
 /* Ported from WINE20030408 */
-CURSORICONDIRENTRY*
-CURSORICON_FindBestCursor( CURSORICONDIR *dir, int width, int height, int colors)
+GRPCURSORICONDIRENTRY*
+CURSORICON_FindBestCursor( GRPCURSORICONDIR *dir, int width, int height, int colors)
 {
     int i;
-    CURSORICONDIRENTRY *entry, *bestEntry = NULL;
+    GRPCURSORICONDIRENTRY *entry, *bestEntry = NULL;
     UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
     UINT iTempXDiff, iTempYDiff, iTempColorDiff;
 
@@ -442,7 +459,7 @@ CURSORICON_FindBestCursor( CURSORICONDIR *dir, int width, int height, int colors
         DPRINT("Empty directory!\n");
         return NULL;
     }
-    if (dir->idCount == 1) 
+    if (dir->idCount == 1)
       return &dir->idEntries[0];  /* No choice... */
 
     /* Find Best Fit */
@@ -450,8 +467,8 @@ CURSORICON_FindBestCursor( CURSORICONDIR *dir, int width, int height, int colors
     iColorDiff = 0xFFFFFFFF;
     for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
     {
-               iTempXDiff = abs(width - entry->Info.icon.bWidth);
-               iTempYDiff = abs(height - entry->Info.icon.bHeight);
+               iTempXDiff = abs(width - entry->ResInfo.icon.bWidth);
+               iTempYDiff = abs(height - entry->ResInfo.icon.bHeight);
 
         if(iTotalDiff > (iTempXDiff + iTempYDiff))
         {
@@ -464,10 +481,10 @@ CURSORICON_FindBestCursor( CURSORICONDIR *dir, int width, int height, int colors
     /* Find Best Colors for Best Fit */
     for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
     {
-        if(abs(width - entry->Info.icon.bWidth) == iXDiff &&
-            abs(height - entry->Info.icon.bHeight) == iYDiff)
+        if(abs(width - entry->ResInfo.icon.bWidth) == (int) iXDiff &&
+            abs(height - entry->ResInfo.icon.bHeight) == (int) iYDiff)
         {
-            iTempColorDiff = abs(colors - entry->Info.icon.bColorCount);
+            iTempColorDiff = abs(colors - entry->ResInfo.icon.bColorCount);
 
             if(iColorDiff > iTempColorDiff)
                {
@@ -481,11 +498,11 @@ CURSORICON_FindBestCursor( CURSORICONDIR *dir, int width, int height, int colors
 }
 
 /* Ported from WINE20030408 */
-CURSORICONDIRENTRY*
-CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width, int height, int colors)
+GRPCURSORICONDIRENTRY*
+CURSORICON_FindBestIcon( GRPCURSORICONDIR *dir, int width, int height, int colorbits)
 {
     int i;
-    CURSORICONDIRENTRY *entry, *bestEntry = NULL;
+    GRPCURSORICONDIRENTRY *entry, *bestEntry = NULL;
     UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
     UINT iTempXDiff, iTempYDiff, iTempColorDiff;
 
@@ -502,9 +519,9 @@ CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width, int height, int colors)
     iColorDiff = 0xFFFFFFFF;
     for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
       {
-       iTempXDiff = abs(width - entry->Info.icon.bWidth);
+       iTempXDiff = abs(width - entry->ResInfo.icon.bWidth);
 
-       iTempYDiff = abs(height - entry->Info.icon.bHeight);
+       iTempYDiff = abs(height - entry->ResInfo.icon.bHeight);
 
         if(iTotalDiff > (iTempXDiff + iTempYDiff))
         {
@@ -517,10 +534,10 @@ CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width, int height, int colors)
     /* Find Best Colors for Best Fit */
     for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
       {
-        if(abs(width - entry->Info.icon.bWidth) == iXDiff &&
-           abs(height - entry->Info.icon.bHeight) == iYDiff)
+        if(abs(width - entry->ResInfo.icon.bWidth) == (int) iXDiff &&
+           abs(height - entry->ResInfo.icon.bHeight) == (int) iYDiff)
         {
-            iTempColorDiff = abs(colors - entry->Info.icon.bColorCount);
+            iTempColorDiff = abs(colorbits - entry->wBitCount);
             if(iColorDiff > iTempColorDiff)
             {
                 bestEntry = entry;
@@ -533,46 +550,47 @@ CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width, int height, int colors)
 }
 
 /* Ported from WINE20030408 */
-int
-STDCALL
+/*
+ * @implemented
+ */
+INT STDCALL
 LookupIconIdFromDirectoryEx(
   PBYTE presbits,
-  WINBOOL fIcon,
+  BOOL fIcon,
   int cxDesired,
   int cyDesired,
   UINT Flags)
 {
-    GRPICONDIR *dir = (GRPICONDIR*)presbits;
-    UINT retVal = 0;
+   GRPCURSORICONDIR *dir = (GRPCURSORICONDIR*)presbits;
+   UINT retVal = 0;
 
-    if( dir && !dir->idReserved && (dir->idType & 3) )
-    {
-       GRPICONDIRENTRY* entry;
-       HDC hdc;
-       UINT palEnts;
-       int colors;
-       hdc = GetDC(0);
-#if 0
-       palEnts = GetSystemPaletteEntries(hdc, 0, 0, NULL);
-       if (palEnts == 0)
-       palEnts = 256;
-#endif
-       palEnts = 16;  //use this until GetSystemPaletteEntries works
-       colors = (Flags & LR_MONOCHROME) ? 2 : palEnts;
-
-       ReleaseDC(0, hdc);
-
-       entry = (GRPICONDIRENTRY*)CURSORICON_FindBestIcon( (CURSORICONDIR*)dir,
-                                                          cxDesired,
-                                                          cyDesired,
-                                                          colors );
-
-       if( entry )
-           retVal = entry->nID;
-    }
-    else
-    {
+   if (dir && !dir->idReserved && (IMAGE_ICON == dir->idType || IMAGE_CURSOR == dir->idType))
+   {
+      GRPCURSORICONDIRENTRY *entry;
+      HDC hdc;
+      int ColorBits;
+
+      hdc = CreateICW(NULL, NULL, NULL, NULL);
+      if (Flags & LR_MONOCHROME)
+      {
+         ColorBits = 1;
+      }
+      else
+      {
+         ColorBits = GetDeviceCaps(hdc, BITSPIXEL);
+         if (ColorBits > 8)
+            ColorBits = 8;
+      }
+      DeleteDC(hdc);
+
+      entry = CURSORICON_FindBestIcon( dir, cxDesired, cyDesired, ColorBits );
+
+      if (entry)
+         retVal = entry->nID;
+   }
+   else
+   {
        DbgPrint("invalid resource directory\n");
-    }
-    return retVal;
+   }
+   return retVal;
 }