[USER32]
authorJérôme Gardou <jerome.gardou@reactos.org>
Mon, 12 Jul 2010 17:49:59 +0000 (17:49 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Mon, 12 Jul 2010 17:49:59 +0000 (17:49 +0000)
  - Rewrite support of cursors, icons and bitmaps in user32.dll, based from WINE implementation.
One file to rule them all.
Now user32::cursoricon winetests don't crash anymore.

svn path=/trunk/; revision=48008

reactos/dll/win32/user32/user32.rbuild
reactos/dll/win32/user32/windows/bitmap.c [deleted file]
reactos/dll/win32/user32/windows/cursor.c [deleted file]
reactos/dll/win32/user32/windows/cursoricon.c [new file with mode: 0644]
reactos/dll/win32/user32/windows/icon.c [deleted file]
reactos/include/reactos/win32k/ntusrtyp.h

index 21ee544..6a08d96 100644 (file)
        </directory>
        <directory name="windows">
                <file>accel.c</file>
-               <file>bitmap.c</file>
                <file>caret.c</file>
                <file>class.c</file>
                <file>clipboard.c</file>
-               <file>cursor.c</file>
+               <file>cursoricon.c</file>
                <file>dc.c</file>
                <file>defwnd.c</file>
                <file>dialog.c</file>
                <file>draw.c</file>
                <file>font.c</file>
                <file>hook.c</file>
-               <file>icon.c</file>
                <file>input.c</file>
                <file>mdi.c</file>
                <file>menu.c</file>
diff --git a/reactos/dll/win32/user32/windows/bitmap.c b/reactos/dll/win32/user32/windows/bitmap.c
deleted file mode 100644 (file)
index 41486c5..0000000
+++ /dev/null
@@ -1,921 +0,0 @@
-/*
- *  ReactOS kernel
- *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/* $Id$
- *
- * PROJECT:         ReactOS user32.dll
- * FILE:            lib/user32/windows/input.c
- * PURPOSE:         Input
- * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
- * UPDATE HISTORY:
- *      09-05-2001  CSH  Created
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <user32.h>
-
-#include <wine/debug.h>
-WINE_DEFAULT_DEBUG_CHANNEL(user32);
-
-#include "pshpack1.h"
-
-typedef struct {
-    BYTE bWidth;
-    BYTE bHeight;
-    BYTE bColorCount;
-    BYTE bReserved;
-    WORD xHotspot;
-    WORD yHotspot;
-    DWORD dwDIBSize;
-    DWORD dwDIBOffset;
-} CURSORICONFILEDIRENTRY;
-
-typedef struct
-{
-    WORD                idReserved;
-    WORD                idType;
-    WORD                idCount;
-    CURSORICONFILEDIRENTRY  idEntries[1];
-} CURSORICONFILEDIR;
-
-#include "poppack.h"
-
-/* forward declarations... actually in user32\windows\icon.c but useful here */
-HICON CreateCursorIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot, BOOL fIcon);
-CURSORICONDIRENTRY *CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width, int height, int colors);
-CURSORICONDIRENTRY *CURSORICON_FindBestCursor( CURSORICONDIR *dir, int width, int height, int colors);
-
-/* FUNCTIONS *****************************************************************/
-
-/*
- * @implemented
- */
-HANDLE WINAPI
-LoadImageA(HINSTANCE hinst,
-          LPCSTR lpszName,
-          UINT uType,
-          int cxDesired,
-          int cyDesired,
-          UINT fuLoad)
-{
-   LPWSTR lpszWName;
-   HANDLE Handle;
-   UNICODE_STRING NameString;
-
-   if (HIWORD(lpszName))
-   {
-      RtlCreateUnicodeStringFromAsciiz(&NameString, (LPSTR)lpszName);
-      lpszWName = NameString.Buffer;
-      Handle = LoadImageW(hinst, lpszWName, uType, cxDesired,
-                         cyDesired, fuLoad);
-      RtlFreeUnicodeString(&NameString);
-   }
-   else
-   {
-      Handle = LoadImageW(hinst, (LPCWSTR)lpszName, uType, cxDesired,
-                         cyDesired, fuLoad);
-   }
-
-   return Handle;
-}
-
-
-/*
- *  The following macro functions account for the irregularities of
- *   accessing cursor and icon resources in files and resource entries.
- */
-typedef BOOL (*fnGetCIEntry)( LPVOID dir, int n,
-                              int *width, int *height, int *bits );
-
-/**********************************************************************
- *         CURSORICON_FindBestCursor2
- *
- * Find the cursor closest to the requested size.
- * FIXME: parameter 'color' ignored and entries with more than 1 bpp
- *        ignored too
- */
-static int CURSORICON_FindBestCursor2( LPVOID dir, fnGetCIEntry get_entry,
-                                      int width, int height, int color )
-{
-    int i, maxwidth, maxheight, cx, cy, bits, bestEntry = -1;
-
-    /* Double height to account for AND and XOR masks */
-
-    height *= 2;
-
-    /* First find the largest one smaller than or equal to the requested size*/
-
-    maxwidth = maxheight = 0;
-    for ( i = 0; get_entry( dir, i, &cx, &cy, &bits ); i++ )
-    {
-        if ((cx <= width) && (cy <= height) &&
-            (cx > maxwidth) && (cy > maxheight) &&
-            (bits == 1))
-        {
-            bestEntry = i;
-            maxwidth  = cx;
-            maxheight = cy;
-        }
-    }
-    if (bestEntry != -1) return bestEntry;
-
-    /* Now find the smallest one larger than the requested size */
-
-    maxwidth = maxheight = 255;
-    for ( i = 0; get_entry( dir, i, &cx, &cy, &bits ); i++ )
-    {
-        if (((cx < maxwidth) && (cy < maxheight) && (bits == 1)) ||
-            (bestEntry==-1))
-        {
-            bestEntry = i;
-            maxwidth  = cx;
-            maxheight = cy;
-        }
-    }
-
-    return bestEntry;
-}
-
-static BOOL CURSORICON_GetFileEntry( LPVOID dir, int n,
-                                     int *width, int *height, int *bits )
-{
-    CURSORICONFILEDIR *filedir = dir;
-    CURSORICONFILEDIRENTRY *entry;
-
-    if ( filedir->idCount <= n )
-        return FALSE;
-    entry = &filedir->idEntries[n];
-    *width = entry->bWidth;
-    *height = entry->bHeight;
-    *bits = entry->bColorCount;
-    return TRUE;
-}
-
-static CURSORICONFILEDIRENTRY *CURSORICON_FindBestCursorFile( CURSORICONFILEDIR *dir,
-                                      int width, int height, int color )
-{
-    int n = CURSORICON_FindBestCursor2( dir, CURSORICON_GetFileEntry,
-                                       width, height, color );
-    if ( n < 0 )
-        return NULL;
-    return &dir->idEntries[n];
-}
-
-static HANDLE
-LoadCursorIconImage(
-   HINSTANCE hinst,
-   LPCWSTR lpszName,
-   INT width,
-   INT height,
-   UINT fuLoad,
-   ULONG uType)
-{
-   HRSRC hResInfo;
-   HANDLE hResource;
-   HANDLE hFile;
-   HANDLE hSection;
-   CURSORICONFILEDIR *IconDIR;
-   HDC hScreenDc;
-   HICON hIcon;
-   ULONG HeaderSize;
-   ULONG ColorCount;
-   ULONG ColorBits;
-   PVOID Data;
-   CURSORICONFILEDIRENTRY* dirEntry;
-   ICONIMAGE* SafeIconImage = NULL;
-   GRPCURSORICONDIR* IconResDir;
-   INT id;
-   ICONIMAGE *ResIcon;
-   BOOL Icon = (uType == IMAGE_ICON);
-   DWORD filesize = 0;
-
-   if (!(fuLoad & LR_LOADFROMFILE))
-   {
-      if (hinst == NULL)
-         hinst = User32Instance;
-
-      hResInfo = FindResourceW(hinst, lpszName,
-                                        Icon ? RT_GROUP_ICON : RT_GROUP_CURSOR);
-      if (hResInfo == NULL)
-         return NULL;
-
-      hResource = LoadResource(hinst, hResInfo);
-      if (hResource == NULL)
-         return NULL;
-
-      IconResDir = LockResource(hResource);
-      if (IconResDir == NULL)
-      {
-         return NULL;
-      }
-
-      /* Find the best fitting in the IconResDir for this resolution */
-      id = LookupIconIdFromDirectoryEx((PBYTE)IconResDir, Icon, width, height,
-                                       fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
-
-      hResInfo = FindResourceW(hinst, MAKEINTRESOURCEW(id),
-                                 Icon ? (LPCWSTR) RT_ICON :
-                                 (LPCWSTR) RT_CURSOR);
-      if (hResInfo == NULL)
-      {
-         return NULL;
-      }
-
-      /* Now we have found the icon we want to load.
-       * Let's see if we already loaded it */
-      if (fuLoad & LR_SHARED)
-      {
-         hIcon = NtUserFindExistingCursorIcon(hinst, hResInfo, 0, 0);
-         if (hIcon)
-         {
-            return hIcon;
-         }
-         else
-             TRACE("Didn't find the shared icon!!\n");
-      }
-
-      hResource = LoadResource(hinst, hResInfo);
-      if (hResource == NULL)
-      {
-         return NULL;
-      }
-
-      ResIcon = LockResource(hResource);
-      if (ResIcon == NULL)
-      {
-         return NULL;
-      }
-
-      hIcon = CreateIconFromResourceEx((PBYTE)ResIcon,
-                                       SizeofResource(hinst, hResInfo),
-                                       Icon, 0x00030000, width, height,
-                                       (fuLoad & (LR_DEFAULTSIZE | LR_SHARED)) | LR_DEFAULTCOLOR);
-
-      if (hIcon && 0 != (fuLoad & LR_SHARED))
-      {
-#if 1
-         NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hinst, hResInfo,
-                                 (HRSRC)NULL);
-#else
-         ICONINFO iconInfo;
-
-         if(NtUserGetIconInfo(ResIcon, &iconInfo, NULL, NULL, NULL, FALSE))
-            NtUserSetCursorIconData((HICON)hIcon, hinst, NULL, &iconInfo);
-#endif
-      }
-
-      return hIcon;
-   }
-
-   if (fuLoad & LR_SHARED)
-   {
-      FIXME("Need LR_SHARED support for loading icon images from files\n");
-   }
-
-   hFile = CreateFileW(lpszName, GENERIC_READ, FILE_SHARE_READ, NULL,
-                       OPEN_EXISTING, 0, NULL);
-   if (hFile == INVALID_HANDLE_VALUE)
-      return NULL;
-
-   hSection = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
-   filesize = GetFileSize( hFile, NULL );
-   CloseHandle(hFile);
-   if (hSection == NULL)
-      return NULL;
-
-   IconDIR = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0);
-   CloseHandle(hSection);
-   if (IconDIR == NULL)
-      return NULL;
-
-   if (0 != IconDIR->idReserved ||
-       (IMAGE_ICON != IconDIR->idType && IMAGE_CURSOR != IconDIR->idType))
-   {
-      UnmapViewOfFile(IconDIR);
-      return NULL;
-   }
-
-   /* Get a handle to the screen dc, the icon we create is going to be
-    * compatable with this. */
-   hScreenDc = CreateDCW(NULL, NULL, NULL, NULL);
-   if (hScreenDc == NULL)
-   {
-      UnmapViewOfFile(IconDIR);
-      RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
-      return NULL;
-   }
-
-   if (fuLoad & LR_MONOCHROME)
-   {
-      ColorBits = 1;
-   }
-   else
-   {
-      ColorBits = GetDeviceCaps(hScreenDc, BITSPIXEL);
-   }
-
-   /* Pick the best size. */
-   dirEntry = CURSORICON_FindBestCursorFile( IconDIR, width, height, ColorBits );
-   if (!dirEntry)
-   {
-      DeleteDC(hScreenDc);
-      UnmapViewOfFile(IconDIR);
-      return NULL;
-   }
-
-   if ( dirEntry->dwDIBOffset > filesize )
-   {
-      DeleteDC(hScreenDc);
-      UnmapViewOfFile(IconDIR);
-      return NULL;
-   }
-
-   if ( dirEntry->dwDIBOffset + dirEntry->dwDIBSize > filesize ){
-      DeleteDC(hScreenDc);
-      UnmapViewOfFile(IconDIR);
-      return NULL;
-   }
-
-   SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwDIBSize);
-   if (SafeIconImage == NULL)
-   {
-      DeleteDC(hScreenDc);
-      UnmapViewOfFile(IconDIR);
-      return NULL;
-   }
-
-   memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwDIBOffset, dirEntry->dwDIBSize);
-   UnmapViewOfFile(IconDIR);
-
-   /* At this point we have a copy of the icon image to play with. */
-
-   SafeIconImage->icHeader.biHeight = SafeIconImage->icHeader.biHeight /2;
-
-   if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))
-   {
-      BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)SafeIconImage;
-      ColorCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
-      HeaderSize = sizeof(BITMAPCOREHEADER) + ColorCount * sizeof(RGBTRIPLE);
-   }
-   else
-   {
-      ColorCount = SafeIconImage->icHeader.biClrUsed;
-      if (ColorCount == 0 && SafeIconImage->icHeader.biBitCount <= 8)
-         ColorCount = 1 << SafeIconImage->icHeader.biBitCount;
-      HeaderSize = sizeof(BITMAPINFOHEADER) + ColorCount * sizeof(RGBQUAD);
-   }
-
-   /* Make data point to the start of the XOR image data. */
-   Data = (PBYTE)SafeIconImage + HeaderSize;
-
-   hIcon = CreateCursorIconFromData(hScreenDc, Data, SafeIconImage, width, height, width/2, height/2, Icon);
-   RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
-   DeleteDC(hScreenDc);
-
-   return hIcon;
-}
-
-
-static HANDLE
-LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
-{
-   HANDLE hResource;
-   HANDLE hFile;
-   HANDLE hSection;
-   LPBITMAPINFO BitmapInfo;
-   LPBITMAPINFO PrivateInfo;
-   HDC hScreenDc;
-   HANDLE hBitmap;
-   ULONG HeaderSize;
-   ULONG ColorCount;
-   PVOID Data;
-   BOOL Hit = FALSE;
-
-   if (!(fuLoad & LR_LOADFROMFILE))
-   {
-      if (hInstance == NULL)
-         hInstance = User32Instance;
-
-      hResource = FindResourceW(hInstance, lpszName, RT_BITMAP);
-      if (hResource == NULL)
-         return NULL;
-      hResource = LoadResource(hInstance, hResource);
-      if (hResource == NULL)
-         return NULL;
-      BitmapInfo = LockResource(hResource);
-      if (BitmapInfo == NULL)
-         return NULL;
-   }
-   else
-   {
-      hFile = CreateFileW(lpszName, GENERIC_READ, FILE_SHARE_READ, NULL,
-                          OPEN_EXISTING, 0, NULL);
-      if (hFile == INVALID_HANDLE_VALUE)
-         return NULL;
-
-      hSection = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
-      CloseHandle(hFile);
-      if (hSection == NULL)
-         return NULL;
-
-      BitmapInfo = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0);
-      CloseHandle(hSection);
-      if (BitmapInfo == NULL)
-         return NULL;
-
-      BitmapInfo = (LPBITMAPINFO)((ULONG_PTR)BitmapInfo + sizeof(BITMAPFILEHEADER));
-   }
-
-   HeaderSize = BitmapInfo->bmiHeader.biSize;
-   if (HeaderSize == sizeof(BITMAPCOREHEADER))
-   {
-      BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)BitmapInfo;
-      ColorCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
-      HeaderSize += ColorCount * sizeof(RGBTRIPLE);
-   }
-   else
-   {
-      if (BitmapInfo->bmiHeader.biCompression == BI_BITFIELDS)
-      {
-         HeaderSize += 3 * sizeof(RGBQUAD);
-      }
-      else
-      {
-         ColorCount = BitmapInfo->bmiHeader.biClrUsed;
-         if (ColorCount == 0 && BitmapInfo->bmiHeader.biBitCount <= 8)
-            ColorCount = 1 << BitmapInfo->bmiHeader.biBitCount;
-         HeaderSize += ColorCount * sizeof(RGBQUAD);
-      }
-   }
-   Data = (PVOID)((ULONG_PTR)BitmapInfo + HeaderSize);
-
-   PrivateInfo = RtlAllocateHeap(GetProcessHeap(), 0, HeaderSize);
-   if (PrivateInfo == NULL)
-   {
-      if (fuLoad & LR_LOADFROMFILE)
-         UnmapViewOfFile(BitmapInfo);
-      return NULL;
-   }
-
-   _SEH2_TRY
-   {
-   memcpy(PrivateInfo, BitmapInfo, HeaderSize);
-   }
-   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-   {
-      Hit = TRUE;
-   }
-   _SEH2_END;
-
-   if (Hit)
-   {
-      ERR("We have a thread overrun, these are already freed! pi -> %d, bi -> %d\n", PrivateInfo, BitmapInfo);
-      RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo);
-      if (fuLoad & LR_LOADFROMFILE)
-         UnmapViewOfFile(BitmapInfo);
-      return NULL;
-   }
-   
-   /* FIXME: Handle color conversion and transparency. */
-
-   hScreenDc = CreateCompatibleDC(NULL);
-   if (hScreenDc == NULL)
-   {
-      RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo);
-      if (fuLoad & LR_LOADFROMFILE)
-         UnmapViewOfFile(BitmapInfo);
-      return NULL;
-   }
-
-   if (fuLoad & LR_CREATEDIBSECTION)
-   {
-      DIBSECTION Dib;
-
-      hBitmap = CreateDIBSection(hScreenDc, PrivateInfo, DIB_RGB_COLORS, NULL,
-                                 0, 0);
-      GetObjectA(hBitmap, sizeof(DIBSECTION), &Dib);
-      SetDIBits(hScreenDc, hBitmap, 0, Dib.dsBm.bmHeight, Data, BitmapInfo,
-                DIB_RGB_COLORS);
-   }
-   else
-   {
-      hBitmap = CreateDIBitmap(hScreenDc, &PrivateInfo->bmiHeader, CBM_INIT,
-                               Data, PrivateInfo, DIB_RGB_COLORS);
-   }
-
-   RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo);
-   DeleteDC(hScreenDc);
-   if (fuLoad & LR_LOADFROMFILE)
-      UnmapViewOfFile(BitmapInfo);
-
-   return hBitmap;
-}
-
-HANDLE WINAPI
-LoadImageW(
-   IN HINSTANCE hinst,
-   IN LPCWSTR lpszName,
-   IN UINT uType,
-   IN INT cxDesired,
-   IN INT cyDesired,
-   IN UINT fuLoad)
-{
-   if (fuLoad & LR_DEFAULTSIZE)
-   {
-      if (uType == IMAGE_ICON)
-      {
-         if (cxDesired == 0)
-            cxDesired = GetSystemMetrics(SM_CXICON);
-         if (cyDesired == 0)
-            cyDesired = GetSystemMetrics(SM_CYICON);
-      }
-      else if (uType == IMAGE_CURSOR)
-      {
-         if (cxDesired == 0)
-            cxDesired = GetSystemMetrics(SM_CXCURSOR);
-         if (cyDesired == 0)
-            cyDesired = GetSystemMetrics(SM_CYCURSOR);
-      }
-   }
-
-   switch (uType)
-   {
-      case IMAGE_BITMAP:
-         return LoadBitmapImage(hinst, lpszName, fuLoad);
-      case IMAGE_CURSOR:
-      case IMAGE_ICON:
-         return LoadCursorIconImage(hinst, lpszName, cxDesired, cyDesired,
-                                    fuLoad, uType);
-      default:
-         break;
-   }
-
-   return NULL;
-}
-
-
-/*
- * @implemented
- */
-HBITMAP WINAPI
-LoadBitmapA(HINSTANCE hInstance, LPCSTR lpBitmapName)
-{
-   return LoadImageA(hInstance, lpBitmapName, IMAGE_BITMAP, 0, 0, 0);
-}
-
-
-/*
- * @implemented
- */
-HBITMAP WINAPI
-LoadBitmapW(HINSTANCE hInstance, LPCWSTR lpBitmapName)
-{
-   return LoadImageW(hInstance, lpBitmapName, IMAGE_BITMAP, 0, 0, 0);
-}
-
-
-static HANDLE
-CopyBmp(HANDLE hnd,
-        UINT type,
-        INT desiredx,
-        INT desiredy,
-        UINT flags)
-{
-    HBITMAP res = NULL;
-    DIBSECTION ds;
-    int objSize;
-    BITMAPINFO * bi;
-
-    objSize = GetObjectW( hnd, sizeof(ds), &ds );
-    if (!objSize) return 0;
-    if ((desiredx < 0) || (desiredy < 0)) return 0;
-
-    if (flags & LR_COPYFROMRESOURCE)
-    {
-        FIXME("FIXME: The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n");
-    }
-
-    if (desiredx == 0) desiredx = ds.dsBm.bmWidth;
-    if (desiredy == 0) desiredy = ds.dsBm.bmHeight;
-
-    /* Allocate memory for a BITMAPINFOHEADER structure and a
-       color table. The maximum number of colors in a color table
-       is 256 which corresponds to a bitmap with depth 8.
-       Bitmaps with higher depths don't have color tables. */
-    bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
-    if (!bi) return 0;
-
-    bi->bmiHeader.biSize        = sizeof(bi->bmiHeader);
-    bi->bmiHeader.biPlanes      = ds.dsBm.bmPlanes;
-    bi->bmiHeader.biBitCount    = ds.dsBm.bmBitsPixel;
-    bi->bmiHeader.biCompression = BI_RGB;
-
-    if (flags & LR_CREATEDIBSECTION)
-    {
-        /* Create a DIB section. LR_MONOCHROME is ignored */
-        void * bits;
-        HDC dc = CreateCompatibleDC(NULL);
-
-        if (objSize == sizeof(DIBSECTION))
-        {
-            /* The source bitmap is a DIB.
-               Get its attributes to create an exact copy */
-            memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
-        }
-
-        /* Get the color table or the color masks */
-        GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
-
-        bi->bmiHeader.biWidth  = desiredx;
-        bi->bmiHeader.biHeight = desiredy;
-        bi->bmiHeader.biSizeImage = 0;
-
-        res = CreateDIBSection(dc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
-        DeleteDC(dc);
-    }
-    else
-    {
-        /* Create a device-dependent bitmap */
-
-        BOOL monochrome = (flags & LR_MONOCHROME);
-
-        if (objSize == sizeof(DIBSECTION))
-        {
-            /* The source bitmap is a DIB section.
-               Get its attributes */
-            HDC dc = CreateCompatibleDC(NULL);
-            bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
-            bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
-            GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
-            DeleteDC(dc);
-
-            if (!monochrome && ds.dsBm.bmBitsPixel == 1)
-            {
-                /* Look if the colors of the DIB are black and white */
-
-                monochrome =
-                      (bi->bmiColors[0].rgbRed == 0xff
-                    && bi->bmiColors[0].rgbGreen == 0xff
-                    && bi->bmiColors[0].rgbBlue == 0xff
-                    && bi->bmiColors[0].rgbReserved == 0
-                    && bi->bmiColors[1].rgbRed == 0
-                    && bi->bmiColors[1].rgbGreen == 0
-                    && bi->bmiColors[1].rgbBlue == 0
-                    && bi->bmiColors[1].rgbReserved == 0)
-                    ||
-                      (bi->bmiColors[0].rgbRed == 0
-                    && bi->bmiColors[0].rgbGreen == 0
-                    && bi->bmiColors[0].rgbBlue == 0
-                    && bi->bmiColors[0].rgbReserved == 0
-                    && bi->bmiColors[1].rgbRed == 0xff
-                    && bi->bmiColors[1].rgbGreen == 0xff
-                    && bi->bmiColors[1].rgbBlue == 0xff
-                    && bi->bmiColors[1].rgbReserved == 0);
-            }
-        }
-        else if (!monochrome)
-        {
-            monochrome = ds.dsBm.bmBitsPixel == 1;
-        }
-
-        if (monochrome)
-        {
-            res = CreateBitmap(desiredx, desiredy, 1, 1, NULL);
-        }
-        else
-        {
-            HDC screenDC = GetDC(NULL);
-            res = CreateCompatibleBitmap(screenDC, desiredx, desiredy);
-            ReleaseDC(NULL, screenDC);
-        }
-    }
-
-    if (res)
-    {
-        /* Only copy the bitmap if it's a DIB section or if it's
-           compatible to the screen */
-        BOOL copyContents;
-
-        if (objSize == sizeof(DIBSECTION))
-        {
-            copyContents = TRUE;
-        }
-        else
-        {
-            HDC screenDC = GetDC(NULL);
-            int screen_depth = GetDeviceCaps(screenDC, BITSPIXEL);
-            ReleaseDC(NULL, screenDC);
-
-            copyContents = (ds.dsBm.bmBitsPixel == 1 || ds.dsBm.bmBitsPixel == screen_depth);
-        }
-
-        if (copyContents)
-        {
-            /* The source bitmap may already be selected in a device context,
-               use GetDIBits/StretchDIBits and not StretchBlt  */
-
-            HDC dc;
-            void * bits;
-
-            dc = CreateCompatibleDC(NULL);
-
-            bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
-            bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
-            bi->bmiHeader.biSizeImage = 0;
-            bi->bmiHeader.biClrUsed = 0;
-            bi->bmiHeader.biClrImportant = 0;
-
-            /* Fill in biSizeImage */
-            GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
-            bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bi->bmiHeader.biSizeImage);
-
-            if (bits)
-            {
-                HBITMAP oldBmp;
-
-                /* Get the image bits of the source bitmap */
-                GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS);
-
-                /* Copy it to the destination bitmap */
-                oldBmp = SelectObject(dc, res);
-                StretchDIBits(dc, 0, 0, desiredx, desiredy,
-                              0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight,
-                              bits, bi, DIB_RGB_COLORS, SRCCOPY);
-                SelectObject(dc, oldBmp);
-
-                HeapFree(GetProcessHeap(), 0, bits);
-            }
-
-            DeleteDC(dc);
-        }
-
-        if (flags & LR_COPYDELETEORG)
-        {
-            DeleteObject(hnd);
-        }
-    }
-    HeapFree(GetProcessHeap(), 0, bi);
-    return res;
-}
-
-
-INT
-GetIconCurBpp(PICONINFO pIconInfo)
-{
-    PBITMAPINFO pbi;
-
-    pbi = (PBITMAPINFO)pIconInfo->hbmColor;
-    return pbi->bmiHeader.biBitCount;
-}
-
-#if 0
-static BOOL
-SetCursorIconData(
-  HANDLE Handle,
-  HINSTANCE hMod,
-  LPWSTR lpResName,
-  PICONINFO pIconInfo)
-{
-
-    UNICODE_STRING Res;
-
-    if (!Handle || !pIconInfo)
-        return FALSE;
-
-    RtlInitUnicodeString(&Res, lpResName);
-
-    return NtUserSetCursorIconData(Handle, hMod, &Res, pIconInfo);
-
-}
-
-
-/* bare bones icon copy implementation */
-static HANDLE
-CopyIcoCur(HANDLE hIconCur,
-           UINT type,
-           INT desiredx,
-           INT desiredy,
-           UINT flags)
-{
-    HANDLE hNewIcon = NULL;
-    ICONINFO origIconInfo, newIconInfo;
-    SIZE origSize;
-    DWORD origBpp;
-
-    if (!hIconCur)
-        return NULL;
-
-    if (flags & LR_COPYFROMRESOURCE)
-    {
-        TRACE("FIXME: LR_COPYFROMRESOURCE is yet not implemented for icons\n");
-    }
-
-    if (NtUserGetIconSize(hIconCur, 0, &origSize.cx, &origSize.cy))
-    {
-        if (desiredx == 0) desiredx = origSize.cx;
-        if (desiredx == 0) desiredy = origSize.cy;
-
-        if (NtUserGetIconInfo(hIconCur, &origIconInfo, NULL, NULL, &origBpp, TRUE))
-        {
-            hNewIcon = (HANDLE)NtUserCallOneParam(0, ONEPARAM_ROUTINE_CREATECURICONHANDLE);
-
-            if (hNewIcon)
-            {
-                /* the bitmaps returned from the NtUserGetIconInfo are copies of the original,
-                 * so we can use these directly to build up our icon/cursor copy */
-                RtlCopyMemory(&newIconInfo, &origIconInfo, sizeof(ICONINFO));
-
-                if (!SetCursorIconData(hNewIcon, NULL, NULL, &newIconInfo))
-                {
-                    if (newIconInfo.fIcon)
-                        DestroyIcon(hNewIcon);
-                    else
-                        DestroyCursor(hNewIcon);
-
-                    hNewIcon = NULL;
-                }
-            }
-
-            DeleteObject(origIconInfo.hbmMask);
-            DeleteObject(origIconInfo.hbmColor);
-        }
-    }
-
-    if (hNewIcon && (flags & LR_COPYDELETEORG))
-    {
-        DestroyCursor((HCURSOR)hIconCur);
-    }
-
-    return hNewIcon;
-}
-#endif
-
-/*
- * @unimplemented
- */
-HANDLE WINAPI
-CopyImage(
-   IN HANDLE hnd,
-   IN UINT type,
-   IN INT desiredx,
-   IN INT desiredy,
-   IN UINT flags)
-{
-/*
- * BUGS
- *    Only Windows NT 4.0 supports the LR_COPYRETURNORG flag for bitmaps,
- *    all other versions (95/2000/XP have been tested) ignore it.
- *
- * NOTES
- *    If LR_CREATEDIBSECTION is absent, the copy will be monochrome for
- *    a monochrome source bitmap or if LR_MONOCHROME is present, otherwise
- *    the copy will have the same depth as the screen.
- *    The content of the image will only be copied if the bit depth of the
- *    original image is compatible with the bit depth of the screen, or
- *    if the source is a DIB section.
- *    The LR_MONOCHROME flag is ignored if LR_CREATEDIBSECTION is present.
- */
-   switch (type)
-   {
-      case IMAGE_BITMAP:
-        return CopyBmp(hnd, type, desiredx, desiredy, flags);
-
-      case IMAGE_ICON:
-        //return CopyIcoCur(hnd, type, desiredx, desiredy, flags);
-          return CopyIcon(hnd);
-
-      case IMAGE_CURSOR:
-         {
-            static BOOL IconMsgDisplayed = FALSE;
-            /* FIXME: support loading the image as shared from an instance */
-            if (!IconMsgDisplayed)
-            {
-               FIXME("FIXME: CopyImage doesn't support IMAGE_CURSOR correctly!\n");
-               IconMsgDisplayed = TRUE;
-            }
-            /* Should call CURSORICON_ExtCopy but more testing
-             * needs to be done before we change this
-             */
-            if (flags) FIXME("FIXME: Flags are ignored\n");
-            return CopyCursor(hnd);
-         }
-   }
-
-   return NULL;
-}
diff --git a/reactos/dll/win32/user32/windows/cursor.c b/reactos/dll/win32/user32/windows/cursor.c
deleted file mode 100644 (file)
index 1119ef1..0000000
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- *  ReactOS kernel
- *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/* $Id$
- *
- * PROJECT:         ReactOS user32.dll
- * FILE:            lib/user32/windows/cursor.c
- * PURPOSE:         Cursor
- * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
- * UPDATE HISTORY:
- *      09-05-2001  CSH  Created
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <user32.h>
-
-#include <wine/debug.h>
-
-WINE_DEFAULT_DEBUG_CHANNEL(user32);
-
-#undef CopyCursor
-
-HBITMAP
-CopyBitmap(HBITMAP bmp);
-
-/* INTERNAL ******************************************************************/
-
-/* This callback routine is called directly after switching to gui mode */
-NTSTATUS
-WINAPI
-User32SetupDefaultCursors(PVOID Arguments,
-                          ULONG ArgumentLength)
-{
-    BOOL *DefaultCursor = (BOOL*)Arguments;
-    LRESULT Result = TRUE;
-
-    if(*DefaultCursor)
-    {
-        /* set default cursor */
-        SetCursor(LoadCursorW(0, (LPCWSTR)IDC_ARROW));
-    }
-    else
-    {
-        /* FIXME load system cursor scheme */
-        SetCursor(0);
-        SetCursor(LoadCursorW(0, (LPCWSTR)IDC_ARROW));
-    }
-
-    return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
-}
-
-/* FUNCTIONS *****************************************************************/
-
-
-/*
- * @implemented
- */
-HCURSOR
-WINAPI
-CopyCursor(HCURSOR pcur)
-{
-    ICONINFO IconInfo;
-
-    if(GetIconInfo((HANDLE)pcur, &IconInfo))
-    {
-        return (HCURSOR)NtUserCreateCursorIconHandle(&IconInfo, FALSE);
-    }
-    return (HCURSOR)0;
-}
-
-/*
- * @implemented
- */
-HCURSOR
-WINAPI
-CreateCursor(HINSTANCE hInst,
-             int xHotSpot,
-             int yHotSpot,
-             int nWidth,
-             int nHeight,
-             CONST VOID *pvANDPlane,
-             CONST VOID *pvXORPlane)
-{
-    ICONINFO IconInfo;
-    BYTE BitmapInfoBuffer[sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD)];
-    BITMAPINFO *bwBIH = (BITMAPINFO *)BitmapInfoBuffer;
-    HDC hScreenDc;
-
-    hScreenDc = CreateCompatibleDC(NULL);
-    if (hScreenDc == NULL)
-        return NULL;
-
-    bwBIH->bmiHeader.biBitCount = 1;
-    bwBIH->bmiHeader.biWidth = nWidth;
-    bwBIH->bmiHeader.biHeight = -nHeight * 2;
-    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;
-
-    IconInfo.hbmMask = CreateDIBitmap(hScreenDc, &bwBIH->bmiHeader, 0,
-                                      NULL, bwBIH, DIB_RGB_COLORS);
-    if (IconInfo.hbmMask)
-    {
-        SetDIBits(hScreenDc, IconInfo.hbmMask, 0, nHeight,
-                  pvXORPlane, bwBIH, DIB_RGB_COLORS);
-        SetDIBits(hScreenDc, IconInfo.hbmMask, nHeight, nHeight,
-                  pvANDPlane, bwBIH, DIB_RGB_COLORS);
-    }
-    else
-    {
-        return NULL;
-    }
-
-    DeleteDC(hScreenDc);
-
-    IconInfo.fIcon = FALSE;
-    IconInfo.xHotspot = xHotSpot;
-    IconInfo.yHotspot = yHotSpot;
-    IconInfo.hbmColor = 0;
-
-    return (HCURSOR)NtUserCreateCursorIconHandle(&IconInfo, FALSE);
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-DestroyCursor(HCURSOR hCursor)
-{
-    return (BOOL)NtUserDestroyCursor((HANDLE)hCursor, 0);
-}
-
-
-/*
- * @implemented
- */
-HCURSOR
-WINAPI
-GetCursor(VOID)
-{
-    CURSORINFO ci;
-    ci.cbSize = sizeof(CURSORINFO);
-    if(NtUserGetCursorInfo(&ci))
-        return ci.hCursor;
-    else
-        return (HCURSOR)0;
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-GetCursorPos(LPPOINT lpPoint)
-{
-    BOOL res;
-    /* Windows doesn't check if lpPoint == NULL, we do */
-    if(!lpPoint)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    res = NtUserGetCursorPos(lpPoint);
-
-    return res;
-}
-
-
-/*
- * @implemented
- */
-HCURSOR
-WINAPI
-LoadCursorA(HINSTANCE hInstance,
-            LPCSTR lpCursorName)
-{
-    return(LoadImageA(hInstance,
-                      lpCursorName,
-                      IMAGE_CURSOR,
-                      0,
-                      0,
-                      LR_SHARED | LR_DEFAULTSIZE));
-}
-
-
-/*
- * @implemented
- */
-HCURSOR
-WINAPI
-LoadCursorFromFileA(LPCSTR lpFileName)
-{
-    UNICODE_STRING FileName;
-    HCURSOR Result;
-    RtlCreateUnicodeStringFromAsciiz(&FileName, (LPSTR)lpFileName);
-    Result = LoadImageW(0,
-                        FileName.Buffer,
-                        IMAGE_CURSOR,
-                        0,
-                        0,
-                        LR_LOADFROMFILE | LR_DEFAULTSIZE);
-    RtlFreeUnicodeString(&FileName);
-    return(Result);
-}
-
-
-/*
- * @implemented
- */
-HCURSOR
-WINAPI
-LoadCursorFromFileW(LPCWSTR lpFileName)
-{
-    return(LoadImageW(0,
-           lpFileName,
-           IMAGE_CURSOR,
-           0,
-           0,
-           LR_LOADFROMFILE | LR_DEFAULTSIZE));
-}
-
-
-/*
- * @implemented
- */
-HCURSOR
-WINAPI
-LoadCursorW(HINSTANCE hInstance,
-            LPCWSTR lpCursorName)
-{
-    return(LoadImageW(hInstance,
-                      lpCursorName,
-                      IMAGE_CURSOR,
-                      0,
-                      0,
-                      LR_SHARED | LR_DEFAULTSIZE));
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-SetCursorPos(int X,
-             int Y)
-{
-    return NtUserSetCursorPos(X,Y);
-}
-
-
-/*
- * @unimplemented
- */
-BOOL
-WINAPI
-SetSystemCursor(HCURSOR hcur,
-                DWORD id)
-{
-    UNIMPLEMENTED;
-    return FALSE;
-}
-
-
-/*
- * @implemented
- */
-int
-WINAPI
-ShowCursor(BOOL bShow)
-{
-    return NtUserShowCursor(bShow);
-}
-
-HCURSOR
-CursorIconToCursor(HICON hIcon,
-                   BOOL SemiTransparent)
-{
-    UNIMPLEMENTED;
-    return 0;
-}
diff --git a/reactos/dll/win32/user32/windows/cursoricon.c b/reactos/dll/win32/user32/windows/cursoricon.c
new file mode 100644 (file)
index 0000000..3729adb
--- /dev/null
@@ -0,0 +1,2074 @@
+/*
+ * Cursor and icon support
+ *
+ * Copyright 1995 Alexandre Julliard
+ *           1996 Martin Von Loewis
+ *           1997 Alex Korobka
+ *           1998 Turchanov Sergey
+ *           2007 Henri Verbeet
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <user32.h>
+
+#include <wine/debug.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(cursor);
+WINE_DECLARE_DEBUG_CHANNEL(icon);
+WINE_DECLARE_DEBUG_CHANNEL(resource);
+
+#include "pshpack1.h"
+
+typedef struct {
+    BYTE bWidth;
+    BYTE bHeight;
+    BYTE bColorCount;
+    BYTE bReserved;
+    WORD xHotspot;
+    WORD yHotspot;
+    DWORD dwDIBSize;
+    DWORD dwDIBOffset;
+} CURSORICONFILEDIRENTRY;
+
+typedef struct
+{
+    WORD                idReserved;
+    WORD                idType;
+    WORD                idCount;
+    CURSORICONFILEDIRENTRY  idEntries[1];
+} CURSORICONFILEDIR;
+
+#include "poppack.h"
+
+static HDC screen_dc;
+
+static const WCHAR DISPLAYW[] = {'D','I','S','P','L','A','Y',0};
+
+
+static CRITICAL_SECTION IconCrst;
+static CRITICAL_SECTION_DEBUG critsect_debug =
+{
+    0, 0, &IconCrst,
+    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": IconCrst") }
+};
+static CRITICAL_SECTION IconCrst = { &critsect_debug, -1, 0, 0, 0, 0 };
+
+
+/***********************************************************************
+ *             map_fileW
+ *
+ * Helper function to map a file to memory:
+ *  name                       -       file name
+ *  [RETURN] ptr               -       pointer to mapped file
+ *  [RETURN] filesize           -       pointer size of file to be stored if not NULL
+ */
+static void *map_fileW( LPCWSTR name, LPDWORD filesize )
+{
+    HANDLE hFile, hMapping;
+    LPVOID ptr = NULL;
+
+    hFile = CreateFileW( name, GENERIC_READ, FILE_SHARE_READ, NULL,
+                         OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0 );
+    if (hFile != INVALID_HANDLE_VALUE)
+    {
+        hMapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
+        if (hMapping)
+        {
+            ptr = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
+            CloseHandle( hMapping );
+            if (filesize)
+                *filesize = GetFileSize( hFile, NULL );
+        }
+        CloseHandle( hFile );
+    }
+    return ptr;
+}
+
+
+/***********************************************************************
+ *          get_dib_width_bytes
+ *
+ * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
+ */
+static int get_dib_width_bytes( int width, int depth )
+{
+    int words;
+
+    switch(depth)
+    {
+    case 1:  words = (width + 31) / 32; break;
+    case 4:  words = (width + 7) / 8; break;
+    case 8:  words = (width + 3) / 4; break;
+    case 15:
+    case 16: words = (width + 1) / 2; break;
+    case 24: words = (width * 3 + 3)/4; break;
+    default:
+        WARN("(%d): Unsupported depth\n", depth );
+        /* fall through */
+    case 32:
+        words = width;
+    }
+    return 4 * words;
+}
+
+
+/***********************************************************************
+ *           bitmap_info_size
+ *
+ * Return the size of the bitmap info structure including color table.
+ */
+static int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
+{
+    unsigned int colors, size, masks = 0;
+
+    if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+    {
+        const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
+        colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
+        return sizeof(BITMAPCOREHEADER) + colors *
+             ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
+    }
+    else  /* assume BITMAPINFOHEADER */
+    {
+        colors = info->bmiHeader.biClrUsed;
+        if (colors > 256) /* buffer overflow otherwise */
+                colors = 256;
+        if (!colors && (info->bmiHeader.biBitCount <= 8))
+            colors = 1 << info->bmiHeader.biBitCount;
+        if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
+        size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
+        return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
+    }
+}
+
+
+/***********************************************************************
+ *          is_dib_monochrome
+ *
+ * Returns whether a DIB can be converted to a monochrome DDB.
+ *
+ * A DIB can be converted if its color table contains only black and
+ * white. Black must be the first color in the color table.
+ *
+ * Note : If the first color in the color table is white followed by
+ *        black, we can't convert it to a monochrome DDB with
+ *        SetDIBits, because black and white would be inverted.
+ */
+static BOOL is_dib_monochrome( const BITMAPINFO* info )
+{
+    if (info->bmiHeader.biBitCount != 1) return FALSE;
+
+    if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+    {
+        const RGBTRIPLE *rgb = ((const BITMAPCOREINFO*)info)->bmciColors;
+
+        /* Check if the first color is black */
+        if ((rgb->rgbtRed == 0) && (rgb->rgbtGreen == 0) && (rgb->rgbtBlue == 0))
+        {
+            rgb++;
+
+            /* Check if the second color is white */
+            return ((rgb->rgbtRed == 0xff) && (rgb->rgbtGreen == 0xff)
+                 && (rgb->rgbtBlue == 0xff));
+        }
+        else return FALSE;
+    }
+    else  /* assume BITMAPINFOHEADER */
+    {
+        const RGBQUAD *rgb = info->bmiColors;
+
+        /* Check if the first color is black */
+        if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) &&
+            (rgb->rgbBlue == 0) && (rgb->rgbReserved == 0))
+        {
+            rgb++;
+
+            /* Check if the second color is white */
+            return ((rgb->rgbRed == 0xff) && (rgb->rgbGreen == 0xff)
+                 && (rgb->rgbBlue == 0xff) && (rgb->rgbReserved == 0));
+        }
+        else return FALSE;
+    }
+}
+
+/***********************************************************************
+ *           DIB_GetBitmapInfo
+ *
+ * Get the info from a bitmap header.
+ * Return 1 for INFOHEADER, 0 for COREHEADER,
+ */
+static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
+                              LONG *height, WORD *bpp, DWORD *compr )
+{
+    if (header->biSize == sizeof(BITMAPCOREHEADER))
+    {
+        const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
+        *width  = core->bcWidth;
+        *height = core->bcHeight;
+        *bpp    = core->bcBitCount;
+        *compr  = 0;
+        return 0;
+    }
+    else if (header->biSize >= sizeof(BITMAPINFOHEADER))
+    {
+        *width  = header->biWidth;
+        *height = header->biHeight;
+        *bpp    = header->biBitCount;
+        *compr  = header->biCompression;
+        return 1;
+    }
+    ERR("(%d): unknown/wrong size for header\n", header->biSize );
+    return -1;
+}
+
+
+/*
+ *  The following macro functions account for the irregularities of
+ *   accessing cursor and icon resources in files and resource entries.
+ */
+typedef BOOL (*fnGetCIEntry)( LPVOID dir, int n,
+                              int *width, int *height, int *bits );
+
+/**********************************************************************
+ *         CURSORICON_FindBestIcon
+ *
+ * Find the icon closest to the requested size and bit depth.
+ */
+static int CURSORICON_FindBestIcon( LPVOID dir, fnGetCIEntry get_entry,
+                                    int width, int height, int depth )
+{
+    int i, cx, cy, bits, bestEntry = -1;
+    UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
+    UINT iTempXDiff, iTempYDiff, iTempColorDiff;
+
+    /* Find Best Fit */
+    iTotalDiff = 0xFFFFFFFF;
+    iColorDiff = 0xFFFFFFFF;
+    for ( i = 0; get_entry( dir, i, &cx, &cy, &bits ); i++ )
+    {
+        iTempXDiff = abs(width - cx);
+        iTempYDiff = abs(height - cy);
+
+        if(iTotalDiff > (iTempXDiff + iTempYDiff))
+        {
+            iXDiff = iTempXDiff;
+            iYDiff = iTempYDiff;
+            iTotalDiff = iXDiff + iYDiff;
+        }
+    }
+
+    /* Find Best Colors for Best Fit */
+    for ( i = 0; get_entry( dir, i, &cx, &cy, &bits ); i++ )
+    {
+        if(abs(width - cx) == iXDiff && abs(height - cy) == iYDiff)
+        {
+            iTempColorDiff = abs(depth - bits);
+            if(iColorDiff > iTempColorDiff)
+            {
+                bestEntry = i;
+                iColorDiff = iTempColorDiff;
+            }
+        }
+    }
+
+    return bestEntry;
+}
+
+static BOOL CURSORICON_GetResIconEntry( LPVOID dir, int n,
+                                        int *width, int *height, int *bits )
+{
+    CURSORICONDIR *resdir = dir;
+    ICONRESDIR *icon;
+
+    if ( resdir->idCount <= n )
+        return FALSE;
+    icon = &resdir->idEntries[n].ResInfo.icon;
+    *width = icon->bWidth;
+    *height = icon->bHeight;
+    *bits = resdir->idEntries[n].wBitCount;
+    return TRUE;
+}
+
+/**********************************************************************
+ *         CURSORICON_FindBestCursor
+ *
+ * Find the cursor closest to the requested size.
+ *
+ * FIXME: parameter 'color' ignored.
+ */
+static int CURSORICON_FindBestCursor( LPVOID dir, fnGetCIEntry get_entry,
+                                      int width, int height, int depth )
+{
+    int i, maxwidth, maxheight, cx, cy, bits, bestEntry = -1;
+
+    /* Double height to account for AND and XOR masks */
+
+    height *= 2;
+
+    /* First find the largest one smaller than or equal to the requested size*/
+
+    maxwidth = maxheight = 0;
+    for ( i = 0; get_entry( dir, i, &cx, &cy, &bits ); i++ )
+    {
+        if ((cx <= width) && (cy <= height) &&
+            (cx > maxwidth) && (cy > maxheight))
+        {
+            bestEntry = i;
+            maxwidth  = cx;
+            maxheight = cy;
+        }
+    }
+    if (bestEntry != -1) return bestEntry;
+
+    /* Now find the smallest one larger than the requested size */
+
+    maxwidth = maxheight = 255;
+    for ( i = 0; get_entry( dir, i, &cx, &cy, &bits ); i++ )
+    {
+        if (((cx < maxwidth) && (cy < maxheight)) || (bestEntry == -1))
+        {
+            bestEntry = i;
+            maxwidth  = cx;
+            maxheight = cy;
+        }
+    }
+
+    return bestEntry;
+}
+
+static BOOL CURSORICON_GetResCursorEntry( LPVOID dir, int n,
+                                          int *width, int *height, int *bits )
+{
+    CURSORICONDIR *resdir = dir;
+    CURSORDIR *cursor;
+
+    if ( resdir->idCount <= n )
+        return FALSE;
+    cursor = &resdir->idEntries[n].ResInfo.cursor;
+    *width = cursor->wWidth;
+    *height = cursor->wHeight;
+    *bits = resdir->idEntries[n].wBitCount;
+    return TRUE;
+}
+
+static CURSORICONDIRENTRY *CURSORICON_FindBestIconRes( CURSORICONDIR * dir,
+                                      int width, int height, int depth )
+{
+    int n;
+
+    n = CURSORICON_FindBestIcon( dir, CURSORICON_GetResIconEntry,
+                                 width, height, depth );
+    if ( n < 0 )
+        return NULL;
+    return &dir->idEntries[n];
+}
+
+static CURSORICONDIRENTRY *CURSORICON_FindBestCursorRes( CURSORICONDIR *dir,
+                                      int width, int height, int depth )
+{
+    int n = CURSORICON_FindBestCursor( dir, CURSORICON_GetResCursorEntry,
+                                   width, height, depth );
+    if ( n < 0 )
+        return NULL;
+    return &dir->idEntries[n];
+}
+
+static BOOL CURSORICON_GetFileEntry( LPVOID dir, int n,
+                                     int *width, int *height, int *bits )
+{
+    CURSORICONFILEDIR *filedir = dir;
+    CURSORICONFILEDIRENTRY *entry;
+    BITMAPINFOHEADER *info;
+
+    if ( filedir->idCount <= n )
+        return FALSE;
+    entry = &filedir->idEntries[n];
+    /* FIXME: check against file size */
+    info = (BITMAPINFOHEADER *)((char *)dir + entry->dwDIBOffset);
+    *width = entry->bWidth;
+    *height = entry->bHeight;
+    *bits = info->biBitCount;
+    return TRUE;
+}
+
+static CURSORICONFILEDIRENTRY *CURSORICON_FindBestCursorFile( CURSORICONFILEDIR *dir,
+                                      int width, int height, int depth )
+{
+    int n = CURSORICON_FindBestCursor( dir, CURSORICON_GetFileEntry,
+                                       width, height, depth );
+    if ( n < 0 )
+        return NULL;
+    return &dir->idEntries[n];
+}
+
+static CURSORICONFILEDIRENTRY *CURSORICON_FindBestIconFile( CURSORICONFILEDIR *dir,
+                                      int width, int height, int depth )
+{
+    int n = CURSORICON_FindBestIcon( dir, CURSORICON_GetFileEntry,
+                                     width, height, depth );
+    if ( n < 0 )
+        return NULL;
+    return &dir->idEntries[n];
+}
+
+/***********************************************************************
+ *          create_icon_bitmaps
+ *
+ * Create the color, mask and alpha bitmaps from the DIB info.
+ */
+static BOOL create_icon_bitmaps( const BITMAPINFO *bmi, int width, int height,
+                                 HBITMAP *color, HBITMAP *mask )
+{
+    BOOL monochrome = is_dib_monochrome( bmi );
+    unsigned int size = bitmap_info_size( bmi, DIB_RGB_COLORS );
+    BITMAPINFO *info;
+    void *color_bits, *mask_bits;
+    BOOL ret = FALSE;
+    HDC hdc = 0;
+
+    if (!(info = HeapAlloc( GetProcessHeap(), 0, max( size, FIELD_OFFSET( BITMAPINFO, bmiColors[2] )))))
+        return FALSE;
+    if (!(hdc = CreateCompatibleDC( 0 ))) goto done;
+
+    memcpy( info, bmi, size );
+    info->bmiHeader.biHeight /= 2;
+
+    color_bits = (char *)bmi + size;
+    mask_bits = (char *)color_bits +
+        get_dib_width_bytes( bmi->bmiHeader.biWidth,
+                             bmi->bmiHeader.biBitCount ) * abs(info->bmiHeader.biHeight);
+
+    if (monochrome)
+    {
+        if (!(*mask = CreateBitmap( width, height * 2, 1, 1, NULL ))) goto done;
+        *color = 0;
+
+        /* copy color data into second half of mask bitmap */
+        SelectObject( hdc, *mask );
+        StretchDIBits( hdc, 0, height, width, height,
+                       0, 0, info->bmiHeader.biWidth, info->bmiHeader.biHeight,
+                       color_bits, info, DIB_RGB_COLORS, SRCCOPY );
+    }
+    else
+    {
+        if (!(*mask = CreateBitmap( width, height, 1, 1, NULL ))) goto done;
+        if (!(*color = CreateBitmap( width, height, GetDeviceCaps( screen_dc, PLANES ),
+                                     GetDeviceCaps( screen_dc, BITSPIXEL ), NULL )))
+        {
+            DeleteObject( *mask );
+            goto done;
+        }
+        SelectObject( hdc, *color );
+        StretchDIBits( hdc, 0, 0, width, height,
+                       0, 0, info->bmiHeader.biWidth, info->bmiHeader.biHeight,
+                       color_bits, info, DIB_RGB_COLORS, SRCCOPY );
+
+        /* convert info to monochrome to copy the mask */
+        info->bmiHeader.biBitCount = 1;
+        if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))
+        {
+            RGBQUAD *rgb = info->bmiColors;
+
+            info->bmiHeader.biClrUsed = info->bmiHeader.biClrImportant = 2;
+            rgb[0].rgbBlue = rgb[0].rgbGreen = rgb[0].rgbRed = 0x00;
+            rgb[1].rgbBlue = rgb[1].rgbGreen = rgb[1].rgbRed = 0xff;
+            rgb[0].rgbReserved = rgb[1].rgbReserved = 0;
+        }
+        else
+        {
+            RGBTRIPLE *rgb = (RGBTRIPLE *)(((BITMAPCOREHEADER *)info) + 1);
+
+            rgb[0].rgbtBlue = rgb[0].rgbtGreen = rgb[0].rgbtRed = 0x00;
+            rgb[1].rgbtBlue = rgb[1].rgbtGreen = rgb[1].rgbtRed = 0xff;
+        }
+    }
+
+    SelectObject( hdc, *mask );
+    StretchDIBits( hdc, 0, 0, width, height,
+                   0, 0, info->bmiHeader.biWidth, info->bmiHeader.biHeight,
+                   mask_bits, info, DIB_RGB_COLORS, SRCCOPY );
+    ret = TRUE;
+
+done:
+    DeleteDC( hdc );
+    HeapFree( GetProcessHeap(), 0, info );
+    return ret;
+}
+
+static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
+                                          POINT hotspot, BOOL bIcon,
+                                          DWORD dwVersion,
+                                          INT width, INT height,
+                                          UINT cFlag )
+{
+    HBITMAP color = 0, mask = 0;
+    BOOL do_stretch;
+       ICONINFO IconInfo;
+
+    if (dwVersion == 0x00020000)
+    {
+        FIXME_(cursor)("\t2.xx resources are not supported\n");
+        return 0;
+    }
+
+    /* Check bitmap header */
+
+    if ( (bmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) &&
+         (bmi->bmiHeader.biSize != sizeof(BITMAPINFOHEADER)  ||
+          bmi->bmiHeader.biCompression != BI_RGB) )
+    {
+          WARN_(cursor)("\tinvalid resource bitmap header.\n");
+          return 0;
+    }
+
+    if (!width) width = bmi->bmiHeader.biWidth;
+    if (!height) height = bmi->bmiHeader.biHeight/2;
+    do_stretch = (bmi->bmiHeader.biHeight/2 != height) ||
+                 (bmi->bmiHeader.biWidth != width);
+
+    /* Scale the hotspot */
+    if (bIcon)
+    {
+        hotspot.x = width / 2;
+        hotspot.y = height / 2;
+    }
+    else if (do_stretch)
+    {
+        hotspot.x = (hotspot.x * width) / bmi->bmiHeader.biWidth;
+        hotspot.y = (hotspot.y * height) / (bmi->bmiHeader.biHeight / 2);
+    }
+
+    if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );
+    if (!screen_dc) return 0;
+
+    if (!create_icon_bitmaps( bmi, width, height, &color, &mask )) return 0;
+
+       IconInfo.xHotspot = hotspot.x;
+       IconInfo.yHotspot = hotspot.y;
+       IconInfo.fIcon = bIcon;
+       IconInfo.hbmColor = color;
+       IconInfo.hbmMask = mask;
+
+       return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
+}
+
+
+/**********************************************************************
+ *          .ANI cursor support
+ */
+#define RIFF_FOURCC( c0, c1, c2, c3 ) \
+        ( (DWORD)(BYTE)(c0) | ( (DWORD)(BYTE)(c1) << 8 ) | \
+        ( (DWORD)(BYTE)(c2) << 16 ) | ( (DWORD)(BYTE)(c3) << 24 ) )
+
+#define ANI_RIFF_ID RIFF_FOURCC('R', 'I', 'F', 'F')
+#define ANI_LIST_ID RIFF_FOURCC('L', 'I', 'S', 'T')
+#define ANI_ACON_ID RIFF_FOURCC('A', 'C', 'O', 'N')
+#define ANI_anih_ID RIFF_FOURCC('a', 'n', 'i', 'h')
+#define ANI_seq__ID RIFF_FOURCC('s', 'e', 'q', ' ')
+#define ANI_fram_ID RIFF_FOURCC('f', 'r', 'a', 'm')
+
+#define ANI_FLAG_ICON       0x1
+#define ANI_FLAG_SEQUENCE   0x2
+
+typedef struct {
+    DWORD header_size;
+    DWORD num_frames;
+    DWORD num_steps;
+    DWORD width;
+    DWORD height;
+    DWORD bpp;
+    DWORD num_planes;
+    DWORD display_rate;
+    DWORD flags;
+} ani_header;
+
+typedef struct {
+    DWORD           data_size;
+    const unsigned char   *data;
+} riff_chunk_t;
+
+static void dump_ani_header( const ani_header *header )
+{
+    TRACE("     header size: %d\n", header->header_size);
+    TRACE("          frames: %d\n", header->num_frames);
+    TRACE("           steps: %d\n", header->num_steps);
+    TRACE("           width: %d\n", header->width);
+    TRACE("          height: %d\n", header->height);
+    TRACE("             bpp: %d\n", header->bpp);
+    TRACE("          planes: %d\n", header->num_planes);
+    TRACE("    display rate: %d\n", header->display_rate);
+    TRACE("           flags: 0x%08x\n", header->flags);
+}
+
+
+/*
+ * RIFF:
+ * DWORD "RIFF"
+ * DWORD size
+ * DWORD riff_id
+ * BYTE[] data
+ *
+ * LIST:
+ * DWORD "LIST"
+ * DWORD size
+ * DWORD list_id
+ * BYTE[] data
+ *
+ * CHUNK:
+ * DWORD chunk_id
+ * DWORD size
+ * BYTE[] data
+ */
+static void riff_find_chunk( DWORD chunk_id, DWORD chunk_type, const riff_chunk_t *parent_chunk, riff_chunk_t *chunk )
+{
+    const unsigned char *ptr = parent_chunk->data;
+    const unsigned char *end = parent_chunk->data + (parent_chunk->data_size - (2 * sizeof(DWORD)));
+
+    if (chunk_type == ANI_LIST_ID || chunk_type == ANI_RIFF_ID) end -= sizeof(DWORD);
+
+    while (ptr < end)
+    {
+        if ((!chunk_type && *(const DWORD *)ptr == chunk_id )
+                || (chunk_type && *(const DWORD *)ptr == chunk_type && *((const DWORD *)ptr + 2) == chunk_id ))
+        {
+            ptr += sizeof(DWORD);
+            chunk->data_size = (*(const DWORD *)ptr + 1) & ~1;
+            ptr += sizeof(DWORD);
+            if (chunk_type == ANI_LIST_ID || chunk_type == ANI_RIFF_ID) ptr += sizeof(DWORD);
+            chunk->data = ptr;
+
+            return;
+        }
+
+        ptr += sizeof(DWORD);
+        ptr += (*(const DWORD *)ptr + 1) & ~1;
+        ptr += sizeof(DWORD);
+    }
+}
+
+
+/*
+ * .ANI layout:
+ *
+ * RIFF:'ACON'                  RIFF chunk
+ *     |- CHUNK:'anih'          Header
+ *     |- CHUNK:'seq '          Sequence information (optional)
+ *     \- LIST:'fram'           Frame list
+ *            |- CHUNK:icon     Cursor frames
+ *            |- CHUNK:icon
+ *            |- ...
+ *            \- CHUNK:icon
+ */
+static HCURSOR CURSORICON_CreateIconFromANI( const LPBYTE bits, DWORD bits_size,
+    INT width, INT height, INT depth )
+{
+    HCURSOR cursor;
+    ani_header header = {0};
+    LPBYTE frame_bits = 0;
+    POINT hotspot;
+    CURSORICONFILEDIRENTRY *entry;
+
+    riff_chunk_t root_chunk = { bits_size, bits };
+    riff_chunk_t ACON_chunk = {0};
+    riff_chunk_t anih_chunk = {0};
+    riff_chunk_t fram_chunk = {0};
+    const unsigned char *icon_data;
+
+    TRACE("bits %p, bits_size %d\n", bits, bits_size);
+
+    if (!bits) return 0;
+
+    riff_find_chunk( ANI_ACON_ID, ANI_RIFF_ID, &root_chunk, &ACON_chunk );
+    if (!ACON_chunk.data)
+    {
+        ERR("Failed to get root chunk.\n");
+        return 0;
+    }
+
+    riff_find_chunk( ANI_anih_ID, 0, &ACON_chunk, &anih_chunk );
+    if (!anih_chunk.data)
+    {
+        ERR("Failed to get 'anih' chunk.\n");
+        return 0;
+    }
+    memcpy( &header, anih_chunk.data, sizeof(header) );
+    dump_ani_header( &header );
+
+    riff_find_chunk( ANI_fram_ID, ANI_LIST_ID, &ACON_chunk, &fram_chunk );
+    if (!fram_chunk.data)
+    {
+        ERR("Failed to get icon list.\n");
+        return 0;
+    }
+
+    /* FIXME: For now, just load the first frame.  Before we can load all the
+     * frames, we need to write the needed code in wineserver, etc. to handle
+     * cursors.  Once this code is written, we can extend it to support .ani
+     * cursors and then update user32 and winex11.drv to load all frames.
+     *
+     * Hopefully this will at least make some games (C&C3, etc.) more playable
+     * in the meantime.
+     */
+    FIXME("Loading all frames for .ani cursors not implemented.\n");
+    icon_data = fram_chunk.data + (2 * sizeof(DWORD));
+
+    entry = CURSORICON_FindBestIconFile( (CURSORICONFILEDIR *) icon_data,
+        width, height, depth );
+
+    frame_bits = HeapAlloc( GetProcessHeap(), 0, entry->dwDIBSize );
+    memcpy( frame_bits, icon_data + entry->dwDIBOffset, entry->dwDIBSize );
+
+    if (!header.width || !header.height)
+    {
+        header.width = entry->bWidth;
+        header.height = entry->bHeight;
+    }
+
+    hotspot.x = entry->xHotspot;
+    hotspot.y = entry->yHotspot;
+
+    cursor = CURSORICON_CreateIconFromBMI( (BITMAPINFO *) frame_bits, hotspot,
+        FALSE, 0x00030000, header.width, header.height, 0 );
+
+    HeapFree( GetProcessHeap(), 0, frame_bits );
+
+    return cursor;
+}
+
+
+/**********************************************************************
+ *             CreateIconFromResourceEx (USER32.@)
+ *
+ * FIXME: Convert to mono when cFlag is LR_MONOCHROME. Do something
+ *        with cbSize parameter as well.
+ */
+HICON WINAPI CreateIconFromResourceEx( PBYTE bits, DWORD cbSize,
+                                       BOOL bIcon, DWORD dwVersion,
+                                       int width, int height,
+                                       UINT cFlag )
+{
+    POINT hotspot;
+    BITMAPINFO *bmi;
+
+    TRACE_(cursor)("%p (%u bytes), ver %08x, %ix%i %s %s\n",
+                   bits, cbSize, dwVersion, width, height,
+                   bIcon ? "icon" : "cursor", (cFlag & LR_MONOCHROME) ? "mono" : "" );
+
+    if (bIcon)
+    {
+        hotspot.x = width / 2;
+        hotspot.y = height / 2;
+        bmi = (BITMAPINFO *)bits;
+    }
+    else /* get the hotspot */
+    {
+        SHORT *pt = (SHORT *)bits;
+        hotspot.x = pt[0];
+        hotspot.y = pt[1];
+        bmi = (BITMAPINFO *)(pt + 2);
+    }
+
+    return CURSORICON_CreateIconFromBMI( bmi, hotspot, bIcon, dwVersion,
+                                        width, height, cFlag );
+}
+
+
+/**********************************************************************
+ *             CreateIconFromResource (USER32.@)
+ */
+HICON WINAPI CreateIconFromResource( PBYTE bits, DWORD cbSize,
+                                           BOOL bIcon, DWORD dwVersion)
+{
+    return CreateIconFromResourceEx( bits, cbSize, bIcon, dwVersion, 0,0,0);
+}
+
+
+static HICON CURSORICON_LoadFromFile( LPCWSTR filename,
+                             INT width, INT height, INT depth,
+                             BOOL fCursor, UINT loadflags)
+{
+    CURSORICONFILEDIRENTRY *entry;
+    CURSORICONFILEDIR *dir;
+    DWORD filesize = 0;
+    HICON hIcon = 0;
+    LPBYTE bits;
+    POINT hotspot;
+
+    TRACE("loading %s\n", debugstr_w( filename ));
+
+    bits = map_fileW( filename, &filesize );
+    if (!bits)
+        return hIcon;
+
+    /* Check for .ani. */
+    if (memcmp( bits, "RIFF", 4 ) == 0)
+    {
+        hIcon = CURSORICON_CreateIconFromANI( bits, filesize, width, height,
+            depth );
+        goto end;
+    }
+
+    dir = (CURSORICONFILEDIR*) bits;
+    if ( filesize < sizeof(*dir) )
+        goto end;
+
+    if ( filesize < (sizeof(*dir) + sizeof(dir->idEntries[0])*(dir->idCount-1)) )
+        goto end;
+
+    if ( fCursor )
+        entry = CURSORICON_FindBestCursorFile( dir, width, height, depth );
+    else
+        entry = CURSORICON_FindBestIconFile( dir, width, height, depth );
+
+    if ( !entry )
+        goto end;
+
+    /* check that we don't run off the end of the file */
+    if ( entry->dwDIBOffset > filesize )
+        goto end;
+    if ( entry->dwDIBOffset + entry->dwDIBSize > filesize )
+        goto end;
+
+    hotspot.x = entry->xHotspot;
+    hotspot.y = entry->yHotspot;
+    hIcon = CURSORICON_CreateIconFromBMI( (BITMAPINFO *)&bits[entry->dwDIBOffset],
+                                         hotspot, !fCursor, 0x00030000,
+                                         width, height, loadflags );
+end:
+    TRACE("loaded %s -> %p\n", debugstr_w( filename ), hIcon );
+    UnmapViewOfFile( bits );
+    return hIcon;
+}
+
+/**********************************************************************
+ *          CURSORICON_Load
+ *
+ * Load a cursor or icon from resource or file.
+ */
+static HICON CURSORICON_Load(HINSTANCE hInstance, LPCWSTR name,
+                             INT width, INT height, INT depth,
+                             BOOL fCursor, UINT loadflags)
+{
+    HANDLE handle = 0;
+    HICON hIcon = 0;
+    HRSRC hRsrc, hGroupRsrc;
+    CURSORICONDIR *dir;
+    CURSORICONDIRENTRY *dirEntry;
+    LPBYTE bits;
+    WORD wResId;
+    DWORD dwBytesInRes;
+
+    TRACE("%p, %s, %dx%d, depth %d, fCursor %d, flags 0x%04x\n",
+          hInstance, debugstr_w(name), width, height, depth, fCursor, loadflags);
+
+    if ( loadflags & LR_LOADFROMFILE )    /* Load from file */
+        return CURSORICON_LoadFromFile( name, width, height, depth, fCursor, loadflags );
+
+    if (!hInstance) hInstance = User32Instance;  /* Load OEM cursor/icon */
+
+    /* don't cache 16-bit instances (FIXME: should never get 16-bit instances in the first place) */
+    if ((ULONG_PTR)hInstance >> 16 == 0) loadflags &= ~LR_SHARED;
+
+    /* Get directory resource ID */
+
+    if (!(hRsrc = FindResourceW( hInstance, name,
+                                 (LPWSTR)(fCursor ? RT_GROUP_CURSOR : RT_GROUP_ICON) )))
+        return 0;
+    hGroupRsrc = hRsrc;
+
+    /* Find the best entry in the directory */
+
+    if (!(handle = LoadResource( hInstance, hRsrc ))) return 0;
+    if (!(dir = LockResource( handle ))) return 0;
+    if (fCursor)
+        dirEntry = CURSORICON_FindBestCursorRes( dir, width, height, depth );
+    else
+        dirEntry = CURSORICON_FindBestIconRes( dir, width, height, depth );
+    if (!dirEntry) return 0;
+    wResId = dirEntry->wResId;
+    dwBytesInRes = dirEntry->dwBytesInRes;
+    FreeResource( handle );
+
+    /* Load the resource */
+
+    if (!(hRsrc = FindResourceW(hInstance,MAKEINTRESOURCEW(wResId),
+                                (LPWSTR)(fCursor ? RT_CURSOR : RT_ICON) ))) return 0;
+
+    /* If shared icon, check whether it was already loaded */
+    if (    (loadflags & LR_SHARED)
+         && (hIcon = NtUserFindExistingCursorIcon( hInstance, hRsrc, 0, 0 ) ) != 0 )
+        return hIcon;
+
+    if (!(handle = LoadResource( hInstance, hRsrc ))) return 0;
+    bits = LockResource( handle );
+    hIcon = CreateIconFromResourceEx( bits, dwBytesInRes,
+                                      !fCursor, 0x00030000, width, height, loadflags);
+    FreeResource( handle );
+
+    /* If shared icon, add to icon cache */
+
+      if (hIcon && 0 != (loadflags & LR_SHARED))
+      {
+#if 1
+         NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hInstance, hRsrc,
+                                 (HRSRC)NULL);
+#else
+         ICONINFO iconInfo;
+
+         if(NtUserGetIconInfo(ResIcon, &iconInfo, NULL, NULL, NULL, FALSE))
+            NtUserSetCursorIconData((HICON)hIcon, hinst, NULL, &iconInfo);
+#endif
+         }
+
+    return hIcon;
+}
+
+
+/*************************************************************************
+ * CURSORICON_ExtCopy
+ *
+ * Copies an Image from the Cache if LR_COPYFROMRESOURCE is specified
+ *
+ * PARAMS
+ *      Handle     [I] handle to an Image
+ *      nType      [I] Type of Handle (IMAGE_CURSOR | IMAGE_ICON)
+ *      iDesiredCX [I] The Desired width of the Image
+ *      iDesiredCY [I] The desired height of the Image
+ *      nFlags     [I] The flags from CopyImage
+ *
+ * RETURNS
+ *     Success: The new handle of the Image
+ *
+ * NOTES
+ *     LR_COPYDELETEORG and LR_MONOCHROME are currently not implemented.
+ *     LR_MONOCHROME should be implemented by CreateIconFromResourceEx.
+ *     LR_COPYFROMRESOURCE will only work if the Image is in the Cache.
+ *
+ *
+ */
+
+static HICON CURSORICON_ExtCopy(HICON hIcon, UINT nType,
+                                INT iDesiredCX, INT iDesiredCY,
+                                UINT nFlags)
+{
+    HICON hNew=0;
+
+    TRACE_(icon)("hIcon %p, nType %u, iDesiredCX %i, iDesiredCY %i, nFlags %u\n",
+                 hIcon, nType, iDesiredCX, iDesiredCY, nFlags);
+
+    if(hIcon == 0)
+    {
+        return 0;
+    }
+
+    /* Best Fit or Monochrome */
+    if( (nFlags & LR_COPYFROMRESOURCE
+        && (iDesiredCX > 0 || iDesiredCY > 0))
+        || nFlags & LR_MONOCHROME)
+    {
+               FIXME("Copying from resource isn't implemented yet\n");
+               hNew = CopyIcon(hIcon);
+
+#if 0
+        ICONCACHE* pIconCache = CURSORICON_FindCache(hIcon);
+
+        /* Not Found in Cache, then do a straight copy
+        */
+        if(pIconCache == NULL)
+        {
+            hNew = CopyIcon( hIcon );
+            if(nFlags & LR_COPYFROMRESOURCE)
+            {
+                TRACE_(icon)("LR_COPYFROMRESOURCE: Failed to load from cache\n");
+            }
+        }
+        else
+        {
+            int iTargetCY = iDesiredCY, iTargetCX = iDesiredCX;
+            LPBYTE pBits;
+            HANDLE hMem;
+            HRSRC hRsrc;
+            DWORD dwBytesInRes;
+            WORD wResId;
+            CURSORICONDIR *pDir;
+            CURSORICONDIRENTRY *pDirEntry;
+            BOOL bIsIcon = (nType == IMAGE_ICON);
+
+            /* Completing iDesiredCX CY for Monochrome Bitmaps if needed
+            */
+            if(((nFlags & LR_MONOCHROME) && !(nFlags & LR_COPYFROMRESOURCE))
+                || (iDesiredCX == 0 && iDesiredCY == 0))
+            {
+                iDesiredCY = GetSystemMetrics(bIsIcon ?
+                    SM_CYICON : SM_CYCURSOR);
+                iDesiredCX = GetSystemMetrics(bIsIcon ?
+                    SM_CXICON : SM_CXCURSOR);
+            }
+
+            /* Retrieve the CURSORICONDIRENTRY
+            */
+            if (!(hMem = LoadResource( pIconCache->hModule ,
+                            pIconCache->hGroupRsrc)))
+            {
+                return 0;
+            }
+            if (!(pDir = LockResource( hMem )))
+            {
+                return 0;
+            }
+
+            /* Find Best Fit
+            */
+            if(bIsIcon)
+            {
+                pDirEntry = CURSORICON_FindBestIconRes(
+                                pDir, iDesiredCX, iDesiredCY, 256 );
+            }
+            else
+            {
+                pDirEntry = CURSORICON_FindBestCursorRes(
+                                pDir, iDesiredCX, iDesiredCY, 1);
+            }
+
+            wResId = pDirEntry->wResId;
+            dwBytesInRes = pDirEntry->dwBytesInRes;
+            FreeResource(hMem);
+
+            TRACE_(icon)("ResID %u, BytesInRes %u, Width %d, Height %d DX %d, DY %d\n",
+                wResId, dwBytesInRes,  pDirEntry->ResInfo.icon.bWidth,
+                pDirEntry->ResInfo.icon.bHeight, iDesiredCX, iDesiredCY);
+
+            /* Get the Best Fit
+            */
+            if (!(hRsrc = FindResourceW(pIconCache->hModule ,
+                MAKEINTRESOURCEW(wResId), (LPWSTR)(bIsIcon ? RT_ICON : RT_CURSOR))))
+            {
+                return 0;
+            }
+            if (!(hMem = LoadResource( pIconCache->hModule , hRsrc )))
+            {
+                return 0;
+            }
+
+            pBits = LockResource( hMem );
+
+            if(nFlags & LR_DEFAULTSIZE)
+            {
+                iTargetCY = GetSystemMetrics(SM_CYICON);
+                iTargetCX = GetSystemMetrics(SM_CXICON);
+            }
+
+            /* Create a New Icon with the proper dimension
+            */
+            hNew = CreateIconFromResourceEx( pBits, dwBytesInRes,
+                       bIsIcon, 0x00030000, iTargetCX, iTargetCY, nFlags);
+            FreeResource(hMem);
+        }
+#endif
+    }
+    else hNew = CopyIcon( hIcon );
+    return hNew;
+}
+
+
+/***********************************************************************
+ *             CreateCursor (USER32.@)
+ */
+HCURSOR WINAPI CreateCursor( HINSTANCE hInstance,
+                                 INT xHotSpot, INT yHotSpot,
+                                 INT nWidth, INT nHeight,
+                                 LPCVOID lpANDbits, LPCVOID lpXORbits )
+{
+    ICONINFO info;
+    HCURSOR hCursor;
+
+    TRACE_(cursor)("%dx%d spot=%d,%d xor=%p and=%p\n",
+                    nWidth, nHeight, xHotSpot, yHotSpot, lpXORbits, lpANDbits);
+
+    info.fIcon = FALSE;
+    info.xHotspot = xHotSpot;
+    info.yHotspot = yHotSpot;
+    info.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, lpANDbits );
+    info.hbmColor = CreateBitmap( nWidth, nHeight, 1, 1, lpXORbits );
+    hCursor = CreateIconIndirect( &info );
+    DeleteObject( info.hbmMask );
+    DeleteObject( info.hbmColor );
+    return hCursor;
+}
+
+
+/***********************************************************************
+ *             CreateIcon (USER32.@)
+ *
+ *  Creates an icon based on the specified bitmaps. The bitmaps must be
+ *  provided in a device dependent format and will be resized to
+ *  (SM_CXICON,SM_CYICON) and depth converted to match the screen's color
+ *  depth. The provided bitmaps must be top-down bitmaps.
+ *  Although Windows does not support 15bpp(*) this API must support it
+ *  for Winelib applications.
+ *
+ *  (*) Windows does not support 15bpp but it supports the 555 RGB 16bpp
+ *      format!
+ *
+ * RETURNS
+ *  Success: handle to an icon
+ *  Failure: NULL
+ *
+ * FIXME: Do we need to resize the bitmaps?
+ */
+HICON WINAPI CreateIcon(
+    HINSTANCE hInstance,  /* [in] the application's hInstance */
+    int       nWidth,     /* [in] the width of the provided bitmaps */
+    int       nHeight,    /* [in] the height of the provided bitmaps */
+    BYTE      bPlanes,    /* [in] the number of planes in the provided bitmaps */
+    BYTE      bBitsPixel, /* [in] the number of bits per pixel of the lpXORbits bitmap */
+    const BYTE*   lpANDbits,  /* [in] a monochrome bitmap representing the icon's mask */
+    const BYTE*   lpXORbits)  /* [in] the icon's 'color' bitmap */
+{
+    ICONINFO iinfo;
+    HICON hIcon;
+
+    TRACE_(icon)("%dx%d, planes %d, bpp %d, xor %p, and %p\n",
+                 nWidth, nHeight, bPlanes, bBitsPixel, lpXORbits, lpANDbits);
+
+    iinfo.fIcon = TRUE;
+    iinfo.xHotspot = nWidth / 2;
+    iinfo.yHotspot = nHeight / 2;
+    iinfo.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, lpANDbits );
+    iinfo.hbmColor = CreateBitmap( nWidth, nHeight, bPlanes, bBitsPixel, lpXORbits );
+
+    hIcon = CreateIconIndirect( &iinfo );
+
+    DeleteObject( iinfo.hbmMask );
+    DeleteObject( iinfo.hbmColor );
+
+    return hIcon;
+}
+
+
+/***********************************************************************
+ *             CopyIcon (USER32.@)
+ */
+HICON WINAPI CopyIcon( HICON hIcon )
+{
+    HICON hRetIcon = NULL;
+    ICONINFO IconInfo;
+
+    if(GetIconInfo(hIcon, &IconInfo))
+    {
+        hRetIcon = CreateIconIndirect(&IconInfo);
+        DeleteObject(IconInfo.hbmColor);
+        DeleteObject(IconInfo.hbmMask);
+    }
+
+    return hRetIcon;
+}
+
+
+/***********************************************************************
+ *             DestroyIcon (USER32.@)
+ */
+BOOL WINAPI DestroyIcon( HICON hIcon )
+{
+    TRACE_(icon)("%p\n", hIcon );
+
+    return NtUserDestroyCursor(hIcon, 0);
+}
+
+
+/***********************************************************************
+ *             DestroyCursor (USER32.@)
+ */
+BOOL WINAPI DestroyCursor( HCURSOR hCursor )
+{
+    if (GetCursor() == hCursor)
+    {
+        WARN_(cursor)("Destroying active cursor!\n" );
+        return FALSE;
+    }
+    return DestroyIcon( hCursor );
+}
+
+/***********************************************************************
+ *             DrawIcon (USER32.@)
+ */
+BOOL WINAPI DrawIcon( HDC hdc, INT x, INT y, HICON hIcon )
+{
+    return DrawIconEx( hdc, x, y, hIcon, 0, 0, 0, 0, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE );
+}
+
+/***********************************************************************
+ *             SetCursor (USER32.@)
+ *
+ * Set the cursor shape.
+ *
+ * RETURNS
+ *     A handle to the previous cursor shape.
+ */
+HCURSOR WINAPI /*DECLSPEC_HOTPATCH*/ SetCursor( HCURSOR hCursor /* [in] Handle of cursor to show */ )
+{
+    return NtUserSetCursor(hCursor);
+}
+
+/***********************************************************************
+ *             ShowCursor (USER32.@)
+ */
+INT WINAPI /*DECLSPEC_HOTPATCH*/ ShowCursor( BOOL bShow )
+{
+    return NtUserShowCursor(bShow);
+}
+
+/***********************************************************************
+ *             GetCursor (USER32.@)
+ */
+HCURSOR WINAPI GetCursor(void)
+{
+    CURSORINFO ci;
+    ci.cbSize = sizeof(CURSORINFO);
+    if(NtUserGetCursorInfo(&ci))
+        return ci.hCursor;
+    else
+        return (HCURSOR)0;
+}
+
+
+/***********************************************************************
+ *             ClipCursor (USER32.@)
+ */
+BOOL WINAPI /*DECLSPEC_HOTPATCH*/ ClipCursor( const RECT *rect )
+{
+    return NtUserClipCursor((RECT *)rect);
+}
+
+
+/***********************************************************************
+ *             GetClipCursor (USER32.@)
+ */
+BOOL WINAPI /*DECLSPEC_HOTPATCH*/ GetClipCursor( RECT *rect )
+{
+    return NtUserGetClipCursor(rect);
+}
+
+
+/***********************************************************************
+ *             SetSystemCursor (USER32.@)
+ */
+BOOL WINAPI SetSystemCursor(HCURSOR hcur, DWORD id)
+{
+    FIXME("(%p,%08x),stub!\n",  hcur, id);
+    return TRUE;
+}
+
+
+/**********************************************************************
+ *             LookupIconIdFromDirectoryEx (USER32.@)
+ */
+INT WINAPI LookupIconIdFromDirectoryEx( LPBYTE xdir, BOOL bIcon,
+             INT width, INT height, UINT cFlag )
+{
+    CURSORICONDIR       *dir = (CURSORICONDIR*)xdir;
+    UINT retVal = 0;
+    if( dir && !dir->idReserved && (dir->idType & 3) )
+    {
+        CURSORICONDIRENTRY* entry;
+
+        const HDC hdc = GetDC(0);
+        const int depth = (cFlag & LR_MONOCHROME) ?
+            1 : GetDeviceCaps(hdc, BITSPIXEL);
+        ReleaseDC(0, hdc);
+
+        if( bIcon )
+            entry = CURSORICON_FindBestIconRes( dir, width, height, depth );
+        else
+            entry = CURSORICON_FindBestCursorRes( dir, width, height, depth );
+
+        if( entry ) retVal = entry->wResId;
+    }
+    else WARN_(cursor)("invalid resource directory\n");
+    return retVal;
+}
+
+/**********************************************************************
+ *              LookupIconIdFromDirectory (USER32.@)
+ */
+INT WINAPI LookupIconIdFromDirectory( LPBYTE dir, BOOL bIcon )
+{
+    return LookupIconIdFromDirectoryEx( dir, bIcon,
+           bIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR),
+           bIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR), bIcon ? 0 : LR_MONOCHROME );
+}
+
+/***********************************************************************
+ *              LoadCursorW (USER32.@)
+ */
+HCURSOR WINAPI LoadCursorW(HINSTANCE hInstance, LPCWSTR name)
+{
+    TRACE("%p, %s\n", hInstance, debugstr_w(name));
+
+    return LoadImageW( hInstance, name, IMAGE_CURSOR, 0, 0,
+                       LR_SHARED | LR_DEFAULTSIZE );
+}
+
+/***********************************************************************
+ *             LoadCursorA (USER32.@)
+ */
+HCURSOR WINAPI LoadCursorA(HINSTANCE hInstance, LPCSTR name)
+{
+    TRACE("%p, %s\n", hInstance, debugstr_a(name));
+
+    return LoadImageA( hInstance, name, IMAGE_CURSOR, 0, 0,
+                       LR_SHARED | LR_DEFAULTSIZE );
+}
+
+/***********************************************************************
+ *             LoadCursorFromFileW (USER32.@)
+ */
+HCURSOR WINAPI LoadCursorFromFileW (LPCWSTR name)
+{
+    TRACE("%s\n", debugstr_w(name));
+
+    return LoadImageW( 0, name, IMAGE_CURSOR, 0, 0,
+                       LR_LOADFROMFILE | LR_DEFAULTSIZE );
+}
+
+/***********************************************************************
+ *             LoadCursorFromFileA (USER32.@)
+ */
+HCURSOR WINAPI LoadCursorFromFileA (LPCSTR name)
+{
+    TRACE("%s\n", debugstr_a(name));
+
+    return LoadImageA( 0, name, IMAGE_CURSOR, 0, 0,
+                       LR_LOADFROMFILE | LR_DEFAULTSIZE );
+}
+
+/***********************************************************************
+ *             LoadIconW (USER32.@)
+ */
+HICON WINAPI LoadIconW(HINSTANCE hInstance, LPCWSTR name)
+{
+    TRACE("%p, %s\n", hInstance, debugstr_w(name));
+
+    return LoadImageW( hInstance, name, IMAGE_ICON, 0, 0,
+                       LR_SHARED | LR_DEFAULTSIZE );
+}
+
+/***********************************************************************
+ *              LoadIconA (USER32.@)
+ */
+HICON WINAPI LoadIconA(HINSTANCE hInstance, LPCSTR name)
+{
+    TRACE("%p, %s\n", hInstance, debugstr_a(name));
+
+    return LoadImageA( hInstance, name, IMAGE_ICON, 0, 0,
+                       LR_SHARED | LR_DEFAULTSIZE );
+}
+
+/**********************************************************************
+ *              GetIconInfo (USER32.@)
+ */
+BOOL WINAPI GetIconInfo(HICON hIcon, PICONINFO iconinfo)
+{
+    return NtUserGetIconInfo(hIcon, iconinfo, 0, 0, 0, 0);
+}
+
+/**********************************************************************
+ *             CreateIconIndirect (USER32.@)
+ */
+HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
+{
+    BITMAP ColorBitmap;
+       BITMAP MaskBitmap;
+
+       if(!iconinfo)
+       {
+               SetLastError(ERROR_INVALID_PARAMETER);
+               return (HICON)0;
+       }
+
+       if(!GetObjectW(iconinfo->hbmMask, sizeof(BITMAP), &MaskBitmap))
+       {
+               return (HICON)0;
+       }
+
+       /* Try to get color bitmap */
+       if (GetObjectW(iconinfo->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;
+               }
+       }
+       return (HICON)NtUserCreateCursorIconHandle(iconinfo, TRUE);
+}
+
+/******************************************************************************
+ *             DrawIconEx (USER32.@) Draws an icon or cursor on device context
+ *
+ * NOTES
+ *    Why is this using SM_CXICON instead of SM_CXCURSOR?
+ *
+ * PARAMS
+ *    hdc     [I] Handle to device context
+ *    x0      [I] X coordinate of upper left corner
+ *    y0      [I] Y coordinate of upper left corner
+ *    hIcon   [I] Handle to icon to draw
+ *    cxWidth [I] Width of icon
+ *    cyWidth [I] Height of icon
+ *    istep   [I] Index of frame in animated cursor
+ *    hbr     [I] Handle to background brush
+ *    flags   [I] Icon-drawing flags
+ *
+ * RETURNS
+ *    Success: TRUE
+ *    Failure: FALSE
+ */
+BOOL WINAPI DrawIconEx( HDC hdc, INT xLeft, INT yTop, HICON hIcon,
+                            INT cxWidth, INT cyWidth, UINT istepIfAniCur,
+                            HBRUSH hbrFlickerFreeDraw, UINT diFlags )
+{
+    return NtUserDrawIconEx(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth,
+                            istepIfAniCur, hbrFlickerFreeDraw, diFlags,
+                            0, 0);
+}
+
+/***********************************************************************
+ *           DIB_FixColorsToLoadflags
+ *
+ * Change color table entries when LR_LOADTRANSPARENT or LR_LOADMAP3DCOLORS
+ * are in loadflags
+ */
+static void DIB_FixColorsToLoadflags(BITMAPINFO * bmi, UINT loadflags, BYTE pix)
+{
+    int colors;
+    COLORREF c_W, c_S, c_F, c_L, c_C;
+    int incr,i;
+    RGBQUAD *ptr;
+    int bitmap_type;
+    LONG width;
+    LONG height;
+    WORD bpp;
+    DWORD compr;
+
+    if (((bitmap_type = DIB_GetBitmapInfo((BITMAPINFOHEADER*) bmi, &width, &height, &bpp, &compr)) == -1))
+    {
+        WARN_(resource)("Invalid bitmap\n");
+        return;
+    }
+
+    if (bpp > 8) return;
+
+    if (bitmap_type == 0) /* BITMAPCOREHEADER */
+    {
+        incr = 3;
+        colors = 1 << bpp;
+    }
+    else
+    {
+        incr = 4;
+        colors = bmi->bmiHeader.biClrUsed;
+        if (colors > 256) colors = 256;
+        if (!colors && (bpp <= 8)) colors = 1 << bpp;
+    }
+
+    c_W = GetSysColor(COLOR_WINDOW);
+    c_S = GetSysColor(COLOR_3DSHADOW);
+    c_F = GetSysColor(COLOR_3DFACE);
+    c_L = GetSysColor(COLOR_3DLIGHT);
+
+    if (loadflags & LR_LOADTRANSPARENT) {
+        switch (bpp) {
+        case 1: pix = pix >> 7; break;
+        case 4: pix = pix >> 4; break;
+        case 8: break;
+        default:
+            WARN_(resource)("(%d): Unsupported depth\n", bpp);
+            return;
+        }
+        if (pix >= colors) {
+            WARN_(resource)("pixel has color index greater than biClrUsed!\n");
+            return;
+        }
+        if (loadflags & LR_LOADMAP3DCOLORS) c_W = c_F;
+        ptr = (RGBQUAD*)((char*)bmi->bmiColors+pix*incr);
+        ptr->rgbBlue = GetBValue(c_W);
+        ptr->rgbGreen = GetGValue(c_W);
+        ptr->rgbRed = GetRValue(c_W);
+    }
+    if (loadflags & LR_LOADMAP3DCOLORS)
+        for (i=0; i<colors; i++) {
+            ptr = (RGBQUAD*)((char*)bmi->bmiColors+i*incr);
+            c_C = RGB(ptr->rgbRed, ptr->rgbGreen, ptr->rgbBlue);
+            if (c_C == RGB(128, 128, 128)) {
+                ptr->rgbRed = GetRValue(c_S);
+                ptr->rgbGreen = GetGValue(c_S);
+                ptr->rgbBlue = GetBValue(c_S);
+            } else if (c_C == RGB(192, 192, 192)) {
+                ptr->rgbRed = GetRValue(c_F);
+                ptr->rgbGreen = GetGValue(c_F);
+                ptr->rgbBlue = GetBValue(c_F);
+            } else if (c_C == RGB(223, 223, 223)) {
+                ptr->rgbRed = GetRValue(c_L);
+                ptr->rgbGreen = GetGValue(c_L);
+                ptr->rgbBlue = GetBValue(c_L);
+            }
+        }
+}
+
+
+/**********************************************************************
+ *       BITMAP_Load
+ */
+static HBITMAP BITMAP_Load( HINSTANCE instance, LPCWSTR name,
+                            INT desiredx, INT desiredy, UINT loadflags )
+{
+    HBITMAP hbitmap = 0, orig_bm;
+    HRSRC hRsrc;
+    HGLOBAL handle;
+    char *ptr = NULL;
+    BITMAPINFO *info, *fix_info = NULL, *scaled_info = NULL;
+    int size;
+    BYTE pix;
+    char *bits;
+    LONG width, height, new_width, new_height;
+    WORD bpp_dummy;
+    DWORD compr_dummy, offbits = 0;
+    INT bm_type;
+    HDC screen_mem_dc = NULL;
+
+    if (!(loadflags & LR_LOADFROMFILE))
+    {
+        if (!instance)
+        {
+            /* OEM bitmap: try to load the resource from user32.dll */
+            instance = User32Instance;
+        }
+
+        if (!(hRsrc = FindResourceW( instance, name, (LPWSTR)RT_BITMAP ))) return 0;
+        if (!(handle = LoadResource( instance, hRsrc ))) return 0;
+
+        if ((info = LockResource( handle )) == NULL) return 0;
+    }
+    else
+    {
+        BITMAPFILEHEADER * bmfh;
+
+        if (!(ptr = map_fileW( name, NULL ))) return 0;
+        info = (BITMAPINFO *)(ptr + sizeof(BITMAPFILEHEADER));
+        bmfh = (BITMAPFILEHEADER *)ptr;
+        if (bmfh->bfType != 0x4d42 /* 'BM' */)
+        {
+            WARN("Invalid/unsupported bitmap format!\n");
+            goto end_close;
+        }
+        if (bmfh->bfOffBits) offbits = bmfh->bfOffBits - sizeof(BITMAPFILEHEADER);
+    }
+
+    size = bitmap_info_size(info, DIB_RGB_COLORS);
+    fix_info = HeapAlloc(GetProcessHeap(), 0, size);
+    scaled_info = HeapAlloc(GetProcessHeap(), 0, size);
+
+    if (!fix_info || !scaled_info) goto end;
+    memcpy(fix_info, info, size);
+
+    pix = *((LPBYTE)info + size);
+    DIB_FixColorsToLoadflags(fix_info, loadflags, pix);
+
+    memcpy(scaled_info, fix_info, size);
+    bm_type = DIB_GetBitmapInfo( &fix_info->bmiHeader, &width, &height,
+                                 &bpp_dummy, &compr_dummy);
+    if(desiredx != 0)
+        new_width = desiredx;
+    else
+        new_width = width;
+
+    if(desiredy != 0)
+        new_height = height > 0 ? desiredy : -desiredy;
+    else
+        new_height = height;
+
+    if(bm_type == 0)
+    {
+        BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)&scaled_info->bmiHeader;
+        core->bcWidth = new_width;
+        core->bcHeight = new_height;
+    }
+    else
+    {
+        /* Some sanity checks for BITMAPINFO (not applicable to BITMAPCOREINFO) */
+        if (info->bmiHeader.biHeight > 65535 || info->bmiHeader.biWidth > 65535) {
+            WARN("Broken BitmapInfoHeader!\n");
+            goto end;
+        }
+
+        scaled_info->bmiHeader.biWidth = new_width;
+        scaled_info->bmiHeader.biHeight = new_height;
+    }
+
+    if (new_height < 0) new_height = -new_height;
+
+    if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );
+    if (!(screen_mem_dc = CreateCompatibleDC( screen_dc ))) goto end;
+
+    bits = (char *)info + (offbits ? offbits : size);
+
+    if (loadflags & LR_CREATEDIBSECTION)
+    {
+        scaled_info->bmiHeader.biCompression = 0; /* DIBSection can't be compressed */
+        hbitmap = CreateDIBSection(screen_dc, scaled_info, DIB_RGB_COLORS, NULL, 0, 0);
+    }
+    else
+    {
+        if (is_dib_monochrome(fix_info))
+            hbitmap = CreateBitmap(new_width, new_height, 1, 1, NULL);
+        else
+            hbitmap = CreateCompatibleBitmap(screen_dc, new_width, new_height);        
+    }
+
+    orig_bm = SelectObject(screen_mem_dc, hbitmap);
+    StretchDIBits(screen_mem_dc, 0, 0, new_width, new_height, 0, 0, width, height, bits, fix_info, DIB_RGB_COLORS, SRCCOPY);
+    SelectObject(screen_mem_dc, orig_bm);
+
+end:
+    if (screen_mem_dc) DeleteDC(screen_mem_dc);
+    HeapFree(GetProcessHeap(), 0, scaled_info);
+    HeapFree(GetProcessHeap(), 0, fix_info);
+end_close:
+    if (loadflags & LR_LOADFROMFILE) UnmapViewOfFile( ptr );
+
+    return hbitmap;
+}
+
+/**********************************************************************
+ *             LoadImageA (USER32.@)
+ *
+ * See LoadImageW.
+ */
+HANDLE WINAPI LoadImageA( HINSTANCE hinst, LPCSTR name, UINT type,
+                              INT desiredx, INT desiredy, UINT loadflags)
+{
+    HANDLE res;
+    LPWSTR u_name;
+
+    if (IS_INTRESOURCE(name))
+        return LoadImageW(hinst, (LPCWSTR)name, type, desiredx, desiredy, loadflags);
+
+    __TRY {
+        DWORD len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
+        u_name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        MultiByteToWideChar( CP_ACP, 0, name, -1, u_name, len );
+    }
+    __EXCEPT_PAGE_FAULT {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+    __ENDTRY
+    res = LoadImageW(hinst, u_name, type, desiredx, desiredy, loadflags);
+    HeapFree(GetProcessHeap(), 0, u_name);
+    return res;
+}
+
+
+/******************************************************************************
+ *             LoadImageW (USER32.@) Loads an icon, cursor, or bitmap
+ *
+ * PARAMS
+ *    hinst     [I] Handle of instance that contains image
+ *    name      [I] Name of image
+ *    type      [I] Type of image
+ *    desiredx  [I] Desired width
+ *    desiredy  [I] Desired height
+ *    loadflags [I] Load flags
+ *
+ * RETURNS
+ *    Success: Handle to newly loaded image
+ *    Failure: NULL
+ *
+ * FIXME: Implementation lacks some features, see LR_ defines in winuser.h
+ */
+HANDLE WINAPI LoadImageW( HINSTANCE hinst, LPCWSTR name, UINT type,
+                INT desiredx, INT desiredy, UINT loadflags )
+{
+    TRACE_(resource)("(%p,%s,%d,%d,%d,0x%08x)\n",
+                     hinst,debugstr_w(name),type,desiredx,desiredy,loadflags);
+
+    if (loadflags & LR_DEFAULTSIZE) {
+        if (type == IMAGE_ICON) {
+            if (!desiredx) desiredx = GetSystemMetrics(SM_CXICON);
+            if (!desiredy) desiredy = GetSystemMetrics(SM_CYICON);
+        } else if (type == IMAGE_CURSOR) {
+            if (!desiredx) desiredx = GetSystemMetrics(SM_CXCURSOR);
+            if (!desiredy) desiredy = GetSystemMetrics(SM_CYCURSOR);
+        }
+    }
+    if (loadflags & LR_LOADFROMFILE) loadflags &= ~LR_SHARED;
+    switch (type) {
+    case IMAGE_BITMAP:
+        return BITMAP_Load( hinst, name, desiredx, desiredy, loadflags );
+
+    case IMAGE_ICON:
+        if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );
+        if (screen_dc)
+        {
+            return CURSORICON_Load(hinst, name, desiredx, desiredy,
+                                   GetDeviceCaps(screen_dc, BITSPIXEL),
+                                   FALSE, loadflags);
+        }
+        break;
+
+    case IMAGE_CURSOR:
+        return CURSORICON_Load(hinst, name, desiredx, desiredy,
+                               1, TRUE, loadflags);
+    }
+    return 0;
+}
+
+/******************************************************************************
+ *             CopyImage (USER32.@) Creates new image and copies attributes to it
+ *
+ * PARAMS
+ *    hnd      [I] Handle to image to copy
+ *    type     [I] Type of image to copy
+ *    desiredx [I] Desired width of new image
+ *    desiredy [I] Desired height of new image
+ *    flags    [I] Copy flags
+ *
+ * RETURNS
+ *    Success: Handle to newly created image
+ *    Failure: NULL
+ *
+ * BUGS
+ *    Only Windows NT 4.0 supports the LR_COPYRETURNORG flag for bitmaps,
+ *    all other versions (95/2000/XP have been tested) ignore it.
+ *
+ * NOTES
+ *    If LR_CREATEDIBSECTION is absent, the copy will be monochrome for
+ *    a monochrome source bitmap or if LR_MONOCHROME is present, otherwise
+ *    the copy will have the same depth as the screen.
+ *    The content of the image will only be copied if the bit depth of the
+ *    original image is compatible with the bit depth of the screen, or
+ *    if the source is a DIB section.
+ *    The LR_MONOCHROME flag is ignored if LR_CREATEDIBSECTION is present.
+ */
+HANDLE WINAPI CopyImage( HANDLE hnd, UINT type, INT desiredx,
+                             INT desiredy, UINT flags )
+{
+    TRACE("hnd=%p, type=%u, desiredx=%d, desiredy=%d, flags=%x\n",
+          hnd, type, desiredx, desiredy, flags);
+
+    switch (type)
+    {
+        case IMAGE_BITMAP:
+        {
+            HBITMAP res = NULL;
+            DIBSECTION ds;
+            int objSize;
+            BITMAPINFO * bi;
+
+            objSize = GetObjectW( hnd, sizeof(ds), &ds );
+            if (!objSize) return 0;
+            if ((desiredx < 0) || (desiredy < 0)) return 0;
+
+            if (flags & LR_COPYFROMRESOURCE)
+            {
+                FIXME("The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n");
+            }
+
+            if (desiredx == 0) desiredx = ds.dsBm.bmWidth;
+            if (desiredy == 0) desiredy = ds.dsBm.bmHeight;
+
+            /* Allocate memory for a BITMAPINFOHEADER structure and a
+               color table. The maximum number of colors in a color table
+               is 256 which corresponds to a bitmap with depth 8.
+               Bitmaps with higher depths don't have color tables. */
+            bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+            if (!bi) return 0;
+
+            bi->bmiHeader.biSize        = sizeof(bi->bmiHeader);
+            bi->bmiHeader.biPlanes      = ds.dsBm.bmPlanes;
+            bi->bmiHeader.biBitCount    = ds.dsBm.bmBitsPixel;
+            bi->bmiHeader.biCompression = BI_RGB;
+
+            if (flags & LR_CREATEDIBSECTION)
+            {
+                /* Create a DIB section. LR_MONOCHROME is ignored */
+                void * bits;
+                HDC dc = CreateCompatibleDC(NULL);
+
+                if (objSize == sizeof(DIBSECTION))
+                {
+                    /* The source bitmap is a DIB.
+                       Get its attributes to create an exact copy */
+                    memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
+                }
+
+                /* Get the color table or the color masks */
+                GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
+
+                bi->bmiHeader.biWidth  = desiredx;
+                bi->bmiHeader.biHeight = desiredy;
+                bi->bmiHeader.biSizeImage = 0;
+
+                res = CreateDIBSection(dc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
+                DeleteDC(dc);
+            }
+            else
+            {
+                /* Create a device-dependent bitmap */
+
+                BOOL monochrome = (flags & LR_MONOCHROME);
+
+                if (objSize == sizeof(DIBSECTION))
+                {
+                    /* The source bitmap is a DIB section.
+                       Get its attributes */
+                    HDC dc = CreateCompatibleDC(NULL);
+                    bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
+                    bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
+                    GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
+                    DeleteDC(dc);
+
+                    if (!monochrome && ds.dsBm.bmBitsPixel == 1)
+                    {
+                        /* Look if the colors of the DIB are black and white */
+
+                        monochrome = 
+                              (bi->bmiColors[0].rgbRed == 0xff
+                            && bi->bmiColors[0].rgbGreen == 0xff
+                            && bi->bmiColors[0].rgbBlue == 0xff
+                            && bi->bmiColors[0].rgbReserved == 0
+                            && bi->bmiColors[1].rgbRed == 0
+                            && bi->bmiColors[1].rgbGreen == 0
+                            && bi->bmiColors[1].rgbBlue == 0
+                            && bi->bmiColors[1].rgbReserved == 0)
+                            ||
+                              (bi->bmiColors[0].rgbRed == 0
+                            && bi->bmiColors[0].rgbGreen == 0
+                            && bi->bmiColors[0].rgbBlue == 0
+                            && bi->bmiColors[0].rgbReserved == 0
+                            && bi->bmiColors[1].rgbRed == 0xff
+                            && bi->bmiColors[1].rgbGreen == 0xff
+                            && bi->bmiColors[1].rgbBlue == 0xff
+                            && bi->bmiColors[1].rgbReserved == 0);
+                    }
+                }
+                else if (!monochrome)
+                {
+                    monochrome = ds.dsBm.bmBitsPixel == 1;
+                }
+
+                if (monochrome)
+                {
+                    res = CreateBitmap(desiredx, desiredy, 1, 1, NULL);
+                }
+                else
+                {
+                    HDC screenDC = GetDC(NULL);
+                    res = CreateCompatibleBitmap(screenDC, desiredx, desiredy);
+                    ReleaseDC(NULL, screenDC);
+                }
+            }
+
+            if (res)
+            {
+                /* Only copy the bitmap if it's a DIB section or if it's
+                   compatible to the screen */
+                BOOL copyContents;
+
+                if (objSize == sizeof(DIBSECTION))
+                {
+                    copyContents = TRUE;
+                }
+                else
+                {
+                    HDC screenDC = GetDC(NULL);
+                    int screen_depth = GetDeviceCaps(screenDC, BITSPIXEL);
+                    ReleaseDC(NULL, screenDC);
+
+                    copyContents = (ds.dsBm.bmBitsPixel == 1 || ds.dsBm.bmBitsPixel == screen_depth);
+                }
+
+                if (copyContents)
+                {
+                    /* The source bitmap may already be selected in a device context,
+                       use GetDIBits/StretchDIBits and not StretchBlt  */
+
+                    HDC dc;
+                    void * bits;
+
+                    dc = CreateCompatibleDC(NULL);
+
+                    bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
+                    bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
+                    bi->bmiHeader.biSizeImage = 0;
+                    bi->bmiHeader.biClrUsed = 0;
+                    bi->bmiHeader.biClrImportant = 0;
+
+                    /* Fill in biSizeImage */
+                    GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
+                    bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bi->bmiHeader.biSizeImage);
+
+                    if (bits)
+                    {
+                        HBITMAP oldBmp;
+
+                        /* Get the image bits of the source bitmap */
+                        GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS);
+
+                        /* Copy it to the destination bitmap */
+                        oldBmp = SelectObject(dc, res);
+                        StretchDIBits(dc, 0, 0, desiredx, desiredy,
+                                      0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight,
+                                      bits, bi, DIB_RGB_COLORS, SRCCOPY);
+                        SelectObject(dc, oldBmp);
+
+                        HeapFree(GetProcessHeap(), 0, bits);
+                    }
+
+                    DeleteDC(dc);
+                }
+
+                if (flags & LR_COPYDELETEORG)
+                {
+                    DeleteObject(hnd);
+                }
+            }
+            HeapFree(GetProcessHeap(), 0, bi);
+            return res;
+        }
+        case IMAGE_ICON:
+                return CURSORICON_ExtCopy(hnd,type, desiredx, desiredy, flags);
+        case IMAGE_CURSOR:
+                /* Should call CURSORICON_ExtCopy but more testing
+                 * needs to be done before we change this
+                 */
+                if (flags) FIXME("Flags are ignored\n");
+                return CopyCursor(hnd);
+    }
+    return 0;
+}
+
+
+/******************************************************************************
+ *             LoadBitmapW (USER32.@) Loads bitmap from the executable file
+ *
+ * RETURNS
+ *    Success: Handle to specified bitmap
+ *    Failure: NULL
+ */
+HBITMAP WINAPI LoadBitmapW(
+    HINSTANCE instance, /* [in] Handle to application instance */
+    LPCWSTR name)         /* [in] Address of bitmap resource name */
+{
+    return LoadImageW( instance, name, IMAGE_BITMAP, 0, 0, 0 );
+}
+
+/**********************************************************************
+ *             LoadBitmapA (USER32.@)
+ *
+ * See LoadBitmapW.
+ */
+HBITMAP WINAPI LoadBitmapA( HINSTANCE instance, LPCSTR name )
+{
+    return LoadImageA( instance, name, IMAGE_BITMAP, 0, 0, 0 );
+}
+
+HCURSOR
+CursorIconToCursor(HICON hIcon,
+                   BOOL SemiTransparent)
+{
+    UNIMPLEMENTED;
+    return 0;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+SetCursorPos(int X,
+             int Y)
+{
+    return NtUserSetCursorPos(X,Y);
+}
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+GetCursorPos(LPPOINT lpPoint)
+{
+    BOOL res;
+    /* Windows doesn't check if lpPoint == NULL, we do */
+    if(!lpPoint)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    res = NtUserGetCursorPos(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 */
+NTSTATUS
+WINAPI
+User32SetupDefaultCursors(PVOID Arguments,
+                          ULONG ArgumentLength)
+{
+    BOOL *DefaultCursor = (BOOL*)Arguments;
+    LRESULT Result = TRUE;
+
+    if(*DefaultCursor)
+    {
+        /* set default cursor */
+        SetCursor(LoadCursorW(0, (LPCWSTR)IDC_ARROW));
+    }
+    else
+    {
+        /* FIXME load system cursor scheme */
+        SetCursor(0);
+        SetCursor(LoadCursorW(0, (LPCWSTR)IDC_ARROW));
+    }
+
+    return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
+}
diff --git a/reactos/dll/win32/user32/windows/icon.c b/reactos/dll/win32/user32/windows/icon.c
deleted file mode 100644 (file)
index b663dcc..0000000
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- *  ReactOS kernel
- *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/*
- * PROJECT:         ReactOS user32.dll
- * FILE:            dll/win32/user32/windows/icon.c
- * PURPOSE:         Icon
- * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
- * UPDATE HISTORY:
- *      09-05-2001  CSH  Created
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <user32.h>
-
-#include <wine/debug.h>
-WINE_DEFAULT_DEBUG_CHANNEL(user32);
-
-/* FUNCTIONS *****************************************************************/
-
-
-HICON
-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 = fIcon;
-   IconInfo.xHotspot = xHotspot;
-   IconInfo.yHotspot = yHotspot;
-
-   if (IconImage->icHeader.biBitCount == 1)
-   {
-       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 = 2;
-       bwBIH->bmiHeader.biClrUsed = 2;
-       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);
-   }
-
-
-   /* Create the icon based on everything we have so far */
-   return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
-}
-
-/*
- * @implemented
- */
-HICON
-WINAPI
-CopyIcon(HICON hIcon)
-{
-    HICON hRetIcon = NULL;
-    ICONINFO IconInfo;
-
-    if(GetIconInfo(hIcon, &IconInfo))
-    {
-        hRetIcon = CreateIconIndirect(&IconInfo);
-        DeleteObject(IconInfo.hbmColor);
-        DeleteObject(IconInfo.hbmMask);
-    }
-
-    return hRetIcon;
-}
-
-
-/*
- * @implemented
- */
-HICON
-WINAPI
-CreateIcon(
-  HINSTANCE hInstance,
-  int nWidth,
-  int nHeight,
-  BYTE cPlanes,
-  BYTE cBitsPixel,
-  CONST BYTE *ANDbits,
-  CONST BYTE *XORbits)
-{
-  ICONINFO IconInfo;
-
-  IconInfo.fIcon = TRUE;
-  
-  if (cBitsPixel == 1)
-  {
-    nHeight <<= 1;
-  }
-  IconInfo.hbmMask = CreateBitmap(nWidth, nHeight, 1, 1, ANDbits);
-  if(!IconInfo.hbmMask)
-  {
-    return (HICON)0;
-  }
-
-  if (cBitsPixel == 1)
-  {
-    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);
-}
-
-
-/*
- * @implemented
- */
-HICON
-WINAPI
-CreateIconFromResource(
-  PBYTE presbits,
-  DWORD dwResSize,
-  BOOL fIcon,
-  DWORD dwVer)
-{
-  return CreateIconFromResourceEx(presbits, dwResSize, fIcon, dwVer, 0, 0, LR_DEFAULTSIZE|LR_SHARED );
-}
-
-
-/*
- * @implemented
- */
-HICON
-WINAPI
-CreateIconFromResourceEx(
-  PBYTE pbIconBits,
-  DWORD cbIconBits,
-  BOOL fIcon,
-  DWORD dwVersion,
-  int cxDesired,
-  int cyDesired,
-  UINT uFlags)
-{
-  ICONIMAGE* SafeIconImage;
-  HICON hIcon;
-  ULONG HeaderSize;
-  ULONG ColourCount;
-  PVOID Data;
-  HDC hScreenDc;
-  WORD wXHotspot;
-  WORD wYHotspot;
-
-  /*
-    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");
-  }
-  */
-
-  TRACE("dwVersion, cxDesired, cyDesired are all ignored in this implementation!\n");
-
-  if (! fIcon)
-    {
-      wXHotspot = *(WORD*)pbIconBits;
-      pbIconBits += sizeof(WORD);
-      wYHotspot = *(WORD*)pbIconBits;
-      pbIconBits += sizeof(WORD);
-      cbIconBits -= 2 * sizeof(WORD);
-    }
-  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 original height was for both the AND and XOR images */
-    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) ?
-                       (1 << SafeIconImage->icHeader.biBitCount) : 0;
-      HeaderSize = sizeof(BITMAPINFOHEADER) + ColourCount * sizeof(RGBQUAD);
-    }
-
-  /* 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 */
-  // FIXME!!! This is a victim of the Win32k Initialization BUG!!!!!
-  //hScreenDc = CreateDCW(NULL, NULL, NULL, NULL);
-  hScreenDc = CreateCompatibleDC(NULL);
-  if (hScreenDc == NULL)
-    {
-      RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
-      return(NULL);
-    }
-
-  hIcon = CreateCursorIconFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired, wXHotspot, wYHotspot, fIcon);
-  RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
-  DeleteDC(hScreenDc);
-
-  return hIcon;
-}
-
-
-/*
- * @implemented
- */
-HICON
-WINAPI
-CreateIconIndirect(PICONINFO IconInfo)
-{
-  BITMAP ColorBitmap;
-  BITMAP MaskBitmap;
-  HBITMAP hbmTemp;
-
-  if(!IconInfo)
-  {
-    SetLastError(ERROR_INVALID_PARAMETER);
-    return (HICON)0;
-  }
-
-  if(!GetObjectW(IconInfo->hbmMask, sizeof(BITMAP), &MaskBitmap))
-  {
-    return (HICON)0;
-  }
-
-  /* Try to get color bitmap */
-  if (GetObjectW(IconInfo->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;
-     }
-     /* 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);
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-DestroyIcon(
-  HICON hIcon)
-{
-  return (BOOL)NtUserDestroyCursor((HANDLE)hIcon, 0);
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-DrawIcon(
-  HDC hDC,
-  int X,
-  int Y,
-  HICON hIcon)
-{
-  return DrawIconEx(hDC, X, Y, hIcon, 0, 0, 0, NULL, DI_NORMAL|DI_DEFAULTSIZE|DI_COMPAT);
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-DrawIconEx(
-  HDC hdc,
-  int xLeft,
-  int yTop,
-  HICON hIcon,
-  int cxWidth,
-  int cyWidth,
-  UINT istepIfAniCur,
-  HBRUSH hbrFlickerFreeDraw,
-  UINT diFlags)
-{
-  return (BOOL)NtUserDrawIconEx(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth,
-                                   istepIfAniCur, hbrFlickerFreeDraw, diFlags,
-                                   0, 0);
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-GetIconInfo(
-  HICON hIcon,
-  PICONINFO IconInfo)
-{
-  return NtUserGetIconInfo((HANDLE)hIcon, IconInfo, 0, 0, 0, 0);
-}
-
-
-/*
- * @implemented
- */
-HICON
-WINAPI
-LoadIconA(
-  HINSTANCE hInstance,
-  LPCSTR lpIconName)
-{
-  return(LoadImageA(hInstance, lpIconName, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE));
-}
-
-
-/*
- * @implemented
- */
-HICON
-WINAPI
-LoadIconW(
-  HINSTANCE hInstance,
-  LPCWSTR lpIconName)
-{
-  return(LoadImageW(hInstance, lpIconName, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE));
-}
-
-
-/*
- * @implemented
- */
-int
-WINAPI
-LookupIconIdFromDirectory(
-  PBYTE presbits,
-  BOOL fIcon)
-{
-    return LookupIconIdFromDirectoryEx(presbits,
-                                       fIcon,
-                                       fIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR),
-                                       fIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR),
-                                       LR_DEFAULTCOLOR);
-}
-
-
-
-
-
-/*
- *  The following macro function accounts for the irregularities of
- *   accessing cursor and icon resources in files and resource entries.
- */
-typedef BOOL
-(*fnGetCIEntry)(LPVOID dir, int n, int *width, int *height, int *bits );
-
-/**********************************************************************
- *         CURSORICON_FindBestIcon
- *
- * Find the icon closest to the requested size and number of colors.
- */
-static int
-CURSORICON_FindBestIcon(LPVOID dir,
-                        fnGetCIEntry get_entry,
-                        int Width,
-                        int Height,
-                        int ColorBits)
-{
-    int i, cx, cy, Bits, BestBits = 0, BestEntry = -1;
-    UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
-    UINT iTempXDiff, iTempYDiff, iTempColorDiff;
-
-    /* Find Best Fit */
-    iTotalDiff = 0xFFFFFFFF;
-    iColorDiff = 0xFFFFFFFF;
-    for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
-    {
-        iTempXDiff = abs(Width - cx);
-        iTempYDiff = abs(Height - cy);
-
-        if(iTotalDiff > (iTempXDiff + iTempYDiff))
-        {
-            iXDiff = iTempXDiff;
-            iYDiff = iTempYDiff;
-            iTotalDiff = iXDiff + iYDiff;
-        }
-    }
-
-    /* Find Best Colors for Best Fit */
-    for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
-    {
-        if(abs(Width - cx) == iXDiff && abs(Height - cy) == iYDiff)
-        {
-            iTempColorDiff = abs(ColorBits - Bits);
-            if(iColorDiff > iTempColorDiff)
-            {
-                BestEntry = i;
-                BestBits = Bits;
-                iColorDiff = iTempColorDiff;
-            }
-        }
-    }
-
-    TRACE("Best Icon: ResId: %d, bits : %d\n", BestEntry, BestBits);
-
-    return BestEntry;
-}
-
-
-
-/**********************************************************************
- *         CURSORICON_FindBestCursor
- *
- * Find the cursor closest to the requested size.
- * FIXME: parameter 'color' ignored and entries with more than 1 bpp
- *        ignored too
- */
-static int
-CURSORICON_FindBestCursor(LPVOID dir,
-                          fnGetCIEntry get_entry,
-                          int Width,
-                          int Height,
-                          int ColorBits)
-{
-    int i, cx, cy, Bits, BestBits = 0, BestEntry = -1;
-    UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
-    UINT iTempXDiff, iTempYDiff, iTempColorDiff;
-
-    /* Find Best Fit */
-    iTotalDiff = 0xFFFFFFFF;
-    iColorDiff = 0xFFFFFFFF;
-    for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
-    {
-        iTempXDiff = abs(Width - cx);
-        iTempYDiff = abs(Height - cy);
-
-        if(iTotalDiff > (iTempXDiff + iTempYDiff))
-        {
-            iXDiff = iTempXDiff;
-            iYDiff = iTempYDiff;
-            iTotalDiff = iXDiff + iYDiff;
-        }
-    }
-
-    /* Find Best Colors for Best Fit */
-    for (i = 0; get_entry(dir, i, &cx, &cy, &Bits); i++ )
-    {
-        if(abs(Width - cx) == iXDiff && abs(Height - cy) == iYDiff)
-        {
-            iTempColorDiff = abs(ColorBits - Bits);
-            if(iColorDiff > iTempColorDiff)
-            {
-                BestEntry = i;
-                BestBits = Bits;
-                iColorDiff = iTempColorDiff;
-            }
-        }
-    }
-
-    TRACE("Best Cursor: ResId: %d, bits : %d\n", BestEntry, BestBits);
-
-    return BestEntry;
-}
-
-
-static BOOL
-CURSORICON_GetResIconEntry(LPVOID dir,
-                           int n,
-                           int *Width,
-                           int *Height,
-                           int *Bits)
-{
-    GRPCURSORICONDIR *ResDir = dir;
-    ICONRESDIR *Icon;
-
-    if (ResDir->idCount <= n)
-        return FALSE;
-
-    Icon = &ResDir->idEntries[n].ResInfo.icon;
-    *Width = Icon->bWidth;
-    *Height = Icon->bHeight;
-    *Bits = ResDir->idEntries[n].wBitCount;
-    return TRUE;
-}
-
-static BOOL
-CURSORICON_GetResCursorEntry(LPVOID dir,
-                             int n,
-                             int *Width,
-                             int *Height,
-                             int *Bits)
-{
-    GRPCURSORICONDIR *ResDir = dir;
-    CURSORRESDIR *Cursor;
-
-    if (ResDir->idCount <= n)
-        return FALSE;
-
-    Cursor = &ResDir->idEntries[n].ResInfo.cursor;
-    *Width = Cursor->wWidth;
-    *Height = Cursor->wHeight;
-    *Bits = ResDir->idEntries[n].wBitCount;
-    return TRUE;
-}
-
-static GRPCURSORICONDIRENTRY *
-CURSORICON_FindBestIconRes(GRPCURSORICONDIR * dir,
-                           int Width,
-                           int Height,
-                           int ColorBits)
-{
-    int n;
-    n = CURSORICON_FindBestIcon(dir,
-                                CURSORICON_GetResIconEntry,
-                                Width,
-                                Height,
-                                ColorBits);
-    if (n < 0)
-        return NULL;
-
-    return &dir->idEntries[n];
-}
-
-static GRPCURSORICONDIRENTRY *
-CURSORICON_FindBestCursorRes(GRPCURSORICONDIR *dir,
-                             int Width,
-                             int Height,
-                             int ColorBits)
-{
-    int n;
-    n = CURSORICON_FindBestCursor(dir,
-                                  CURSORICON_GetResCursorEntry,
-                                  Width,
-                                  Height,
-                                  ColorBits);
-    if (n < 0)
-        return NULL;
-
-    return &dir->idEntries[n];
-}
-
-
-INT WINAPI
-LookupIconIdFromDirectoryEx(PBYTE xdir,
-                            BOOL bIcon,
-                            INT width,
-                            INT height,
-                            UINT cFlag)
-{
-    GRPCURSORICONDIR *dir = (GRPCURSORICONDIR*)xdir;
-    UINT retVal = 0;
-
-    GetConnected();
-
-    if(dir && !dir->idReserved && (IMAGE_ICON == dir->idType || IMAGE_CURSOR == dir->idType))
-    {
-        GRPCURSORICONDIRENTRY *entry = NULL;
-        int ColorBits;
-
-        if (cFlag & LR_MONOCHROME)
-        {
-            ColorBits = 1;
-        }
-        else if (cFlag & LR_VGACOLOR)
-        {
-            ColorBits = 4;
-        }
-        else
-        {
-            ColorBits = gpsi->BitsPixel;
-        }
-
-        if(bIcon)
-            entry = CURSORICON_FindBestIconRes(dir, width, height, ColorBits);
-        else
-            entry = CURSORICON_FindBestCursorRes(dir, width, height, 1);
-
-        if (entry)
-            retVal = entry->nID;
-    }
-    else
-        WARN("%s() : Invalid resource directory\n", __FUNCTION__);
-
-    return retVal;
-}
index 3d40ac8..b54bc9b 100644 (file)
@@ -82,31 +82,27 @@ typedef struct
 
 typedef struct
 {
-    WORD wXHotspot;                 // Number of Color Planes in the XOR image
-    WORD wYHotspot;                 // Bits per pixel in the XOR image
+    WORD   wWidth;
+    WORD   wHeight;
 } CURSORDIR;
 
 typedef struct
-{
-    BYTE bWidth;                    // Width, in pixels, of the icon image
-    BYTE bHeight;                   // Height, in pixels, of the icon image
-    BYTE bColorCount;               // Number of colors in image (0 if >=8bpp)
-    BYTE bReserved;                 // Reserved ( must be 0)
-    union
-    {
-        ICONDIR icon;
-        CURSORDIR  cursor;
-    } Info;
-    DWORD dwBytesInRes;             // How many bytes in this resource?
-    DWORD dwImageOffset;            // Where in the file is this image?
+{   union
+    { ICONRESDIR icon;
+      CURSORDIR  cursor;
+    } ResInfo;
+    WORD   wPlanes;
+    WORD   wBitCount;
+    DWORD  dwBytesInRes;
+    WORD   wResId;
 } CURSORICONDIRENTRY;
 
 typedef struct
 {
-    WORD idReserved;                // Reserved (must be 0)
-    WORD idType;                    // Resource Type (1 for icons, 0 for cursors)
-    WORD idCount;                   // How many images?
-    CURSORICONDIRENTRY idEntries[1];// An entry for idCount number of images
+    WORD                idReserved;
+    WORD                idType;
+    WORD                idCount;
+    CURSORICONDIRENTRY  idEntries[1];
 } CURSORICONDIR;
 
 typedef struct