[user32]
[reactos.git] / reactos / dll / win32 / user32 / windows / icon.c
index 173aa8a..5840b89 100644 (file)
@@ -37,117 +37,77 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32);
 
 
 HICON
-ICON_CreateIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot)
+CreateCursorIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot, BOOL fIcon)
 {
    BYTE BitmapInfoBuffer[sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD)];
    BITMAPINFO *bwBIH = (BITMAPINFO *)BitmapInfoBuffer;
    ICONINFO IconInfo;
 
-   IconInfo.fIcon = TRUE;
+   IconInfo.fIcon = fIcon;
    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->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);
-}
-
-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)
+   if (IconImage->icHeader.biBitCount == 1)
    {
-      SetDIBits(hDC, IconInfo.hbmMask, 0, IconImage->icHeader.biHeight,
-                XORImageData, bwBIH, DIB_RGB_COLORS);
+       IconInfo.hbmColor = (HBITMAP)0;
+       IconImage->icHeader.biHeight *= 2;
+       IconInfo.hbmMask = CreateDIBitmap(hDC, &IconImage->icHeader, CBM_INIT,
+                                  ImageData, (BITMAPINFO*)IconImage,
+                                  DIB_RGB_COLORS);
+   }
+   else
+   {
+       /* Create 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 monochrome 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;
+
+       /* Create 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);
    }
 
-   IconInfo.hbmColor = (HBITMAP)0;
 
    /* Create the icon based on everything we have so far */
    return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
 }
 
-
 /*
  * @implemented
  */
 HICON
-STDCALL
+WINAPI
 CopyIcon(HICON hIcon)
 {
     HICON hRetIcon = NULL;
@@ -168,7 +128,7 @@ CopyIcon(HICON hIcon)
  * @implemented
  */
 HICON
-STDCALL
+WINAPI
 CreateIcon(
   HINSTANCE hInstance,
   int nWidth,
@@ -181,18 +141,29 @@ CreateIcon(
   ICONINFO IconInfo;
 
   IconInfo.fIcon = TRUE;
-  IconInfo.xHotspot = nWidth / 2;
-  IconInfo.yHotspot = nHeight / 2;
+  
+  if (cBitsPixel == 1)
+  {
+    nHeight <<= 1;
+  }
   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)
+
+  if (cBitsPixel == 1)
   {
-    DeleteObject(IconInfo.hbmMask);
-    return (HICON)0;
+    IconInfo.hbmColor = (HBITMAP)0;
+  }
+  else
+  {
+    IconInfo.hbmColor = CreateBitmap(nWidth, nHeight, cPlanes, cBitsPixel, XORbits);
+    if(!IconInfo.hbmColor)
+    { 
+       DeleteObject(IconInfo.hbmMask);
+       return (HICON)0;
+    }
   }
 
   return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
@@ -203,7 +174,7 @@ CreateIcon(
  * @implemented
  */
 HICON
-STDCALL
+WINAPI
 CreateIconFromResource(
   PBYTE presbits,
   DWORD dwResSize,
@@ -218,7 +189,7 @@ CreateIconFromResource(
  * @implemented
  */
 HICON
-STDCALL
+WINAPI
 CreateIconFromResourceEx(
   PBYTE pbIconBits,
   DWORD cbIconBits,
@@ -270,8 +241,7 @@ CreateIconFromResourceEx(
     }
   memcpy(SafeIconImage, pbIconBits, cbIconBits);
 
-  /* take into acount the original height was for both the AND and XOR images */
-  if(fIcon)
+  /* Take into acount the original height was for both the AND and XOR images */
     SafeIconImage->icHeader.biHeight /= 2;
 
   if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))
@@ -291,6 +261,8 @@ CreateIconFromResourceEx(
   Data = (PBYTE)SafeIconImage + HeaderSize;
 
   /* get a handle to the screen dc, the icon we create is going to be compatable with this */
+  // FIXME!!! This is a victim of the Win32k Initialization BUG!!!!!
+  //hScreenDc = CreateDCW(NULL, NULL, NULL, NULL);
   hScreenDc = CreateCompatibleDC(NULL);
   if (hScreenDc == NULL)
     {
@@ -298,10 +270,7 @@ CreateIconFromResourceEx(
       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);
+  hIcon = CreateCursorIconFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired, wXHotspot, wYHotspot, fIcon);
   RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
   DeleteDC(hScreenDc);
 
@@ -313,11 +282,12 @@ CreateIconFromResourceEx(
  * @implemented
  */
 HICON
-STDCALL
+WINAPI
 CreateIconIndirect(PICONINFO IconInfo)
 {
   BITMAP ColorBitmap;
   BITMAP MaskBitmap;
+  HBITMAP hbmTemp;
 
   if(!IconInfo)
   {
@@ -329,20 +299,26 @@ CreateIconIndirect(PICONINFO IconInfo)
   {
     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)
+  /* Try to get color bitmap */
+  if (GetObjectW(IconInfo->hbmColor, sizeof(BITMAP), &ColorBitmap))
   {
-    SetLastError(ERROR_INVALID_PARAMETER);
-    return (HICON)0;
-  }*/
-
+     /* 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;
+     }
+     /* Check if color and mask are switched and switch them back */
+     if (MaskBitmap.bmBitsPixel != 1 && ColorBitmap.bmBitsPixel == 1)
+     {
+        hbmTemp = IconInfo->hbmMask;
+        IconInfo->hbmMask = IconInfo->hbmColor;
+        IconInfo->hbmColor = hbmTemp;
+     }
+  }
   return (HICON)NtUserCreateCursorIconHandle(IconInfo, TRUE);
 }
 
@@ -351,7 +327,7 @@ CreateIconIndirect(PICONINFO IconInfo)
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 DestroyIcon(
   HICON hIcon)
 {
@@ -363,7 +339,7 @@ DestroyIcon(
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 DrawIcon(
   HDC hDC,
   int X,
@@ -377,7 +353,7 @@ DrawIcon(
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 DrawIconEx(
   HDC hdc,
   int xLeft,
@@ -399,7 +375,7 @@ DrawIconEx(
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 GetIconInfo(
   HICON hIcon,
   PICONINFO IconInfo)
@@ -412,7 +388,7 @@ GetIconInfo(
  * @implemented
  */
 HICON
-STDCALL
+WINAPI
 LoadIconA(
   HINSTANCE hInstance,
   LPCSTR lpIconName)
@@ -425,7 +401,7 @@ LoadIconA(
  * @implemented
  */
 HICON
-STDCALL
+WINAPI
 LoadIconW(
   HINSTANCE hInstance,
   LPCWSTR lpIconName)
@@ -438,7 +414,7 @@ LoadIconW(
  * @implemented
  */
 int
-STDCALL
+WINAPI
 LookupIconIdFromDirectory(
   PBYTE presbits,
   BOOL fIcon)
@@ -656,6 +632,9 @@ LookupIconIdFromDirectoryEx(PBYTE xdir,
 {
     GRPCURSORICONDIR *dir = (GRPCURSORICONDIR*)xdir;
     UINT retVal = 0;
+
+    GetConnected();
+
     if(dir && !dir->idReserved && (IMAGE_ICON == dir->idType || IMAGE_CURSOR == dir->idType))
     {
         GRPCURSORICONDIRENTRY *entry = NULL;
@@ -665,11 +644,13 @@ LookupIconIdFromDirectoryEx(PBYTE xdir,
         {
             ColorBits = 1;
         }
+        else if (cFlag & LR_VGACOLOR)
+        {
+            ColorBits = 4;
+        }
         else
         {
-            HDC hdc = CreateICW(NULL, NULL, NULL, NULL);
-            ColorBits = GetDeviceCaps(hdc, BITSPIXEL);
-            DeleteDC(hdc);
+            ColorBits = gpsi->BitsPixel;
         }
 
         if(bIcon)