Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

winicon.cpp

Go to the documentation of this file.
00001 /* $Id: winicon.cpp,v 1.33 2001/10/27 10:30:11 sandervl Exp $ */
00002 /*
00003  * Win32 Icon Code for OS/2
00004  *
00005  *
00006  * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl) (OS/2 Port)
00007  *
00008  * Based on Wine code (objects\bitmap.c, loader\resource.c, objects\cursoricon.c):
00009  *
00010  * Copyright 1993 Alexandre Julliard
00011  *           1993 Robert J. Amstadt
00012  *           1996 Martin Von Loewis
00013  *           1997 Alex Korobka
00014  *           1998 Turchanov Sergey
00015  *           1998 Huw D M Davies
00016  * Theory:
00017  *
00018  * http://www.microsoft.com/win32dev/ui/icons.htm
00019  *
00020  * Cursors and icons are stored in a global heap block, with the
00021  * following layout:
00022  *
00023  * CURSORICONINFO info;
00024  * BYTE[]         ANDbits;
00025  * BYTE[]         XORbits;
00026  *
00027  * The bits structures are in the format of a device-dependent bitmap.
00028  *
00029  * This layout is very sub-optimal, as the bitmap bits are stored in
00030  * the X client instead of in the server like other bitmaps; however,
00031  * some programs (notably Paint Brush) expect to be able to manipulate
00032  * the bits directly :-(
00033  *
00034  * FIXME: what are we going to do with animation and color (bpp > 1) cursors ?!
00035  *
00036  **************************************************************************************************
00037  *
00038  * TODO: Scaling of system cursors (store them as resources in user32 instead of using PM pointers)
00039  * TODO: We use the hColorBmp member of the CURSORICONINFO structure to store the PM cursor handle
00040  *       Might mess up PaintBrush (see above)
00041  *
00042  * Project Odin Software License can be found in LICENSE.TXT
00043  *
00044  */
00045 #include <os2win.h>
00046 #include <stdio.h>
00047 #include <string.h>
00048 #include <winicon.h>
00049 #include <win\cursoricon.h>
00050 #include <objhandle.h>
00051 #include "dib.h"
00052 #include <heapstring.h>
00053 #include <win\virtual.h>
00054 #include "initterm.h"
00055 #include "oslibres.h"
00056 #include "oslibwin.h"
00057 #include "dc.h"
00058 
00059 #define DBG_LOCALLOG    DBG_winicon
00060 #include "dbglocal.h"
00061 
00062 
00063 /**********************************************************************
00064  * ICONCACHE for cursors/icons loaded with LR_SHARED.
00065  *
00066  * FIXME: This should not be allocated on the system heap, but on a
00067  *        subsystem-global heap (i.e. one for all Win16 processes,
00068  *        and one for each Win32 process).
00069  */
00070 typedef struct tagICONCACHE
00071 {
00072     struct tagICONCACHE *next;
00073 
00074     HMODULE              hModule;
00075     HRSRC                hRsrc;
00076     HRSRC                hGroupRsrc;
00077     HANDLE               handle;
00078     INT                  count;
00079 } ICONCACHE;
00080 
00081 static ICONCACHE *IconAnchor = NULL;
00082 static CRITICAL_SECTION IconCrst = CRITICAL_SECTION_INIT;
00083 static WORD    ICON_HOTSPOT  = 0x4242;
00084 static HCURSOR hActiveCursor = 0;
00085 static HCURSOR hActiveCursorPM = 0;
00086 
00087 
00088 static HGLOBAL CURSORICON_CreateFromResource( HINSTANCE hInstance, DWORD dwResGroupId, HGLOBAL hObj, LPBYTE bits,
00089                                               UINT cbSize, BOOL bIcon, DWORD dwVersion, INT width, INT height, UINT loadflags );
00090 static HGLOBAL CURSORICON_Copy( HGLOBAL handle );
00091 static CURSORICONDIRENTRY *CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width,
00092                                                     int height, int colors );
00093 static CURSORICONDIRENTRY *CURSORICON_FindBestCursor( CURSORICONDIR *dir,
00094                                                   int width, int height, int color);
00095 BOOL CURSORICON_SimulateLoadingFromResourceW( LPWSTR filename, BOOL fCursor,
00096                                                 CURSORICONDIR **res, LPBYTE **ptr);
00097 
00098 static INT CURSORICON_DelSharedIcon( HANDLE handle );
00099 static void CURSORICON_AddSharedIcon( HMODULE hModule, HRSRC hRsrc, HRSRC hGroupRsrc, HANDLE handle );
00100 static HANDLE CURSORICON_FindSharedIcon( HMODULE hModule, HRSRC hRsrc );
00101 static ICONCACHE* CURSORICON_FindCache(HANDLE handle);
00102 
00103 static HGLOBAL CreateCursorIconIndirect( HINSTANCE hInstance,
00104                                          CURSORICONINFO *info,
00105                                          LPCVOID lpANDbits,
00106                                          LPCVOID lpXORbits, BOOL fIcon);
00107 
00108 /***********************************************************************
00109  *           CreateIcon    (USER32.75)
00110  */
00111 HICON WIN32API CreateIcon(HINSTANCE hInstance, INT nWidth,
00112                           INT nHeight, BYTE bPlanes, BYTE bBitsPixel,
00113                           LPCVOID lpANDbits, LPCVOID lpXORbits )
00114 {
00115     CURSORICONINFO info;
00116 
00117     dprintf(("USER32: CreateIcon (%d,%d), %d, %x, %x", nWidth, nHeight, bPlanes * bBitsPixel, lpXORbits, lpANDbits));
00118 
00119     info.ptHotSpot.x = ICON_HOTSPOT;
00120     info.ptHotSpot.y = ICON_HOTSPOT;
00121     info.nWidth = nWidth;
00122     info.nHeight = nHeight;
00123     info.nWidthBytes = 0;
00124     info.bPlanes = bPlanes;
00125     info.bBitsPerPixel = bBitsPixel;
00126     info.hInstance = hInstance;
00127     info.dwResGroupId = -1;
00128     info.hColorBmp = 0;
00129     return CreateCursorIconIndirect(0, &info, lpANDbits, lpXORbits, TRUE);
00130 }
00131 /**********************************************************************
00132  *          CreateIconFromResource          (USER32.76)
00133  */
00134 HICON WIN32API CreateIconFromResource(LPBYTE bits, UINT cbSize,
00135                                       BOOL bIcon, DWORD dwVersion)
00136 {
00137     return CreateIconFromResourceEx( bits, cbSize, bIcon, dwVersion, 0,0,0);
00138 }
00139 //******************************************************************************
00140 //******************************************************************************
00141 HICON WIN32API CreateIconFromResourceEx(LPBYTE bits, UINT cbSize,
00142                                         BOOL bIcon, DWORD dwVersion,
00143                                         INT width, INT height,
00144                                         UINT cFlag )
00145 {
00146     dprintf(("USER32:  CreateIconFromResourceEx %X %d %d %X %d %d %X,", bits, cbSize, bIcon, dwVersion, width, height, cFlag));
00147     return CURSORICON_CreateFromResource(0, -1, 0, bits, cbSize, bIcon, dwVersion, width, height, cFlag );
00148 }
00149 /**********************************************************************
00150  *          CreateIconIndirect      (USER32.78)
00151  */
00152 HICON WINAPI CreateIconIndirect(ICONINFO *iconinfo)
00153 {
00154     BITMAP bmpXor,bmpAnd;
00155     HICON hObj;
00156     int sizeXor,sizeAnd,colortablesize;
00157 
00158     dprintf(("USER32: CreateIconIndirect %x %x %x %s", iconinfo, iconinfo->hbmMask, iconinfo->hbmColor, (iconinfo->fIcon) ? "icon" : "cursor"));
00159 
00160     GetObjectA( iconinfo->hbmColor, sizeof(bmpXor), &bmpXor );
00161     GetObjectA( iconinfo->hbmMask, sizeof(bmpAnd), &bmpAnd );
00162 
00163     colortablesize = 0;
00164 
00165     if(bmpXor.bmBitsPixel <= 8) {
00166          colortablesize = sizeof(RGBQUAD)*(1<<bmpXor.bmBitsPixel);
00167          sizeXor = bmpXor.bmHeight * bmpXor.bmWidthBytes + colortablesize;
00168     }
00169     else sizeXor = bmpXor.bmHeight * bmpXor.bmWidthBytes;
00170 
00171     sizeAnd = bmpAnd.bmHeight * bmpAnd.bmWidthBytes;
00172 
00173     hObj = GlobalAlloc( GMEM_MOVEABLE, sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
00174     if (hObj)
00175     {
00176         CURSORICONINFO *info;
00177 
00178         info = (CURSORICONINFO *)GlobalLock( hObj );
00179 
00180         /* If we are creating an icon, the hotspot is unused */
00181         if (iconinfo->fIcon)
00182         {
00183             info->ptHotSpot.x   = ICON_HOTSPOT;
00184             info->ptHotSpot.y   = ICON_HOTSPOT;
00185         }
00186         else
00187         {
00188             info->ptHotSpot.x   = iconinfo->xHotspot;
00189             info->ptHotSpot.y   = iconinfo->yHotspot;
00190         }
00191 
00192         info->nWidth        = bmpXor.bmWidth;
00193         info->nHeight       = bmpXor.bmHeight;
00194         info->nWidthBytes   = bmpXor.bmWidthBytes;
00195         info->bPlanes       = bmpXor.bmPlanes;
00196         info->bBitsPerPixel = bmpXor.bmBitsPixel;
00197         info->hInstance     = -1;
00198         info->dwResGroupId  = -1;
00199         info->hColorBmp     = 0;
00200 
00201         /* Transfer the bitmap bits to the CURSORICONINFO structure */
00202         GetBitmapBits( iconinfo->hbmMask ,sizeAnd,(char*)(info + 1) );
00203         if(bmpXor.bmBitsPixel > 1)
00204         {
00205             BITMAPINFO* pInfo = (BITMAPINFO *)malloc(sizeof(BITMAPINFO)+colortablesize+3*sizeof(DWORD)); //+ extra space for > 8bpp images
00206             HBITMAP oldbmp;
00207             HDC     hdc;
00208 
00209             hdc = CreateCompatibleDC(0);
00210 
00211             memset(pInfo, 0, sizeof(BITMAPINFO)+colortablesize+3*sizeof(DWORD));
00212             pInfo->bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
00213             pInfo->bmiHeader.biPlanes   = info->bPlanes;
00214             pInfo->bmiHeader.biBitCount = info->bBitsPerPixel;
00215 
00216             GetDIBits(hdc, iconinfo->hbmColor, 0, bmpXor.bmHeight, (char *)(info + 1) + sizeAnd + colortablesize, pInfo, DIB_RGB_COLORS);
00217             if(colortablesize) {
00218                 memcpy((char *)(info + 1) + sizeAnd, (char *)&pInfo->bmiHeader + pInfo->bmiHeader.biSize, colortablesize);
00219             }
00220 
00221             DeleteDC(hdc);
00222             free(pInfo);
00223         }
00224         else {
00225             GetBitmapBits( iconinfo->hbmColor,sizeXor,(char*)(info + 1) +sizeAnd);
00226         }
00227 
00228 #ifdef __WIN32OS2__
00229         info->hColorBmp = OSLibWinCreatePointer(info, (char*)(info + 1), (LPBITMAP_W)&bmpAnd, (char*)(info + 1) + sizeAnd, (LPBITMAP_W)&bmpXor, iconinfo->fIcon == FALSE);
00230 #endif
00231         GlobalUnlock(hObj);
00232 
00233 #ifdef __WIN32OS2__
00234         HICON hIcon;
00235         if(ObjAllocateHandle(&hIcon, (DWORD)hObj, USEROBJ_CURSORICON) == FALSE) {
00236             GlobalFree(hObj);
00237             dprintf(("ERROR: CreateIconIndirect ObjAllocateHandle failed!!"));
00238             return 0;
00239         }
00240 #endif
00241         dprintf(("USER32: CreateIconIndirect %x returned %x", iconinfo, hIcon));
00242         return hIcon;
00243     }
00244     else {
00245         dprintf(("ERROR: CreateIconIndirect GlobalAlloc failed!!"));
00246         return 0;
00247     }
00248 }
00249 //******************************************************************************
00250 //******************************************************************************
00251 BOOL WIN32API DestroyIcon( HICON hIcon)
00252 {
00253     dprintf(("USER32: DestroyIcon %x", hIcon));
00254     return CURSORICON_Destroy( hIcon, 0 );
00255 }
00256 //******************************************************************************
00257 //******************************************************************************
00258 HICON WIN32API CopyIcon( HICON hIcon)
00259 {
00260     dprintf(("USER32:  CopyIcon %x", hIcon));
00261     return CURSORICON_Copy( hIcon );
00262 }
00263 //******************************************************************************
00264 //******************************************************************************
00265 HICON WIN32API GetOS2Icon(HICON hIcon)
00266 {
00267     CURSORICONINFO  *ciconinfo;
00268 
00269     hIcon = ObjGetHandleData(hIcon, USEROBJ_CURSORICON);
00270     if(hIcon == -1) {
00271         dprintf(("ERROR: Invalid cursor/icon!"));
00272         return 0;
00273     }
00274     ciconinfo = (CURSORICONINFO *)GlobalLock((HGLOBAL)hIcon);
00275     if (!ciconinfo)
00276         return 0;
00277     HICON hOS2Icon = ciconinfo->hColorBmp;
00278     GlobalUnlock(hIcon);
00279     return hOS2Icon;
00280 }
00281 /**********************************************************************
00282  *          GetIconInfo     (USER32.242)
00283  */
00284 BOOL WINAPI GetIconInfo(HICON hIcon, ICONINFO *iconinfo)
00285 {
00286     CURSORICONINFO  *ciconinfo;
00287 
00288     dprintf(("GetIconInfo %x %x", hIcon, iconinfo));
00289 
00290 #ifdef __WIN32OS2__
00291     hIcon = ObjGetHandleData(hIcon, USEROBJ_CURSORICON);
00292     if(hIcon == -1) {
00293         dprintf(("ERROR: Invalid cursor/icon!"));
00294         return 0;
00295     }
00296 #endif
00297     ciconinfo = (CURSORICONINFO *)GlobalLock((HGLOBAL)hIcon);
00298     if (!ciconinfo)
00299         return FALSE;
00300 
00301     if((ciconinfo->ptHotSpot.x == ICON_HOTSPOT) &&
00302        (ciconinfo->ptHotSpot.y == ICON_HOTSPOT))
00303     {
00304         iconinfo->fIcon    = TRUE;
00305         iconinfo->xHotspot = ciconinfo->nWidth / 2;
00306         iconinfo->yHotspot = ciconinfo->nHeight / 2;
00307     }
00308     else
00309     {
00310         iconinfo->fIcon    = FALSE;
00311         iconinfo->xHotspot = ciconinfo->ptHotSpot.x;
00312         iconinfo->yHotspot = ciconinfo->ptHotSpot.y;
00313     }
00314 
00315     //Create new bitmaps for the color and mask data; application is responsible
00316     //for deleteing them (according to docs & verified in NT4)
00317     if(ciconinfo->bBitsPerPixel > 1)
00318     {
00319         BITMAPINFO* pInfo;
00320         int colorsize = 0;
00321         int coloroff;
00322 
00323         HDC hdc = CreateCompatibleDC(0);
00324 
00325         if(ciconinfo->bBitsPerPixel <= 8) {
00326             colorsize = (1<<ciconinfo->bBitsPerPixel)*sizeof(RGBQUAD);
00327         }
00328         else {
00329             colorsize = 3*sizeof(DWORD); //color masks
00330         }
00331         pInfo = (BITMAPINFO *)malloc(ciconinfo->nHeight * ciconinfo->nWidthBytes + colorsize + sizeof(BITMAPINFO));
00332         memset(pInfo, 0, sizeof(BITMAPINFO)+colorsize);
00333 
00334         pInfo->bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
00335         pInfo->bmiHeader.biWidth    = ciconinfo->nWidth;
00336         pInfo->bmiHeader.biHeight   = ciconinfo->nHeight,
00337         pInfo->bmiHeader.biPlanes   = ciconinfo->bPlanes;
00338         pInfo->bmiHeader.biBitCount = ciconinfo->bBitsPerPixel;
00339         pInfo->bmiHeader.biSizeImage= ciconinfo->nHeight * ciconinfo->nWidthBytes;
00340 
00341         //offset in cursorinfo memory
00342         coloroff = ciconinfo->nHeight * BITMAP_GetWidthBytes (ciconinfo->nWidth, 1);
00343 
00344         char *src  = (char *)(ciconinfo + 1) + coloroff;
00345         if(ciconinfo->bBitsPerPixel <= 8) {
00346             src += colorsize;       //no color masks in cursorinfo data for bpp > 8
00347         }
00348         if(ciconinfo->bBitsPerPixel <= 8) {
00349                 memcpy(&pInfo->bmiColors[0], (char *)(ciconinfo + 1) + coloroff, colorsize);
00350         }
00351         //else TODO: color masks (currently unused in CreateDIBitmap)
00352 
00353         iconinfo->hbmColor = CreateDIBitmap(hdc, &pInfo->bmiHeader, CBM_INIT, src, pInfo, DIB_RGB_COLORS);
00354 
00355         free(pInfo);
00356         DeleteDC(hdc);
00357     }
00358     else {
00359         iconinfo->hbmColor = CreateBitmap ( ciconinfo->nWidth, ciconinfo->nHeight,
00360                                             ciconinfo->bPlanes, ciconinfo->bBitsPerPixel,
00361                                             (char *)(ciconinfo + 1)
00362                                             + ciconinfo->nHeight *
00363                                             BITMAP_GetWidthBytes (ciconinfo->nWidth, 1) );
00364     }
00365 
00366     iconinfo->hbmMask = CreateBitmap ( ciconinfo->nWidth, ciconinfo->nHeight,
00367                                 1, 1, (char *)(ciconinfo + 1));
00368 
00369     GlobalUnlock(hIcon);
00370 
00371     return TRUE;
00372 }
00373 //******************************************************************************
00374 //******************************************************************************
00375 HCURSOR WIN32API CreateCursor(HINSTANCE hInst, int xHotSpot, int yHotSpot, int nWidth, int nHeight,
00376                               const VOID *lpANDbits, const VOID *lpXORbits)
00377 {
00378     CURSORICONINFO info;
00379 
00380     dprintf(("CreateCursor %dx%d spot=%d,%d xor=%p and=%p\n",
00381              nWidth, nHeight, xHotSpot, yHotSpot, lpXORbits, lpANDbits));
00382 
00383     info.ptHotSpot.x   = xHotSpot;
00384     info.ptHotSpot.y   = yHotSpot;
00385     info.nWidth        = nWidth;
00386     info.nHeight       = nHeight;
00387     info.nWidthBytes   = 0;
00388     info.bPlanes       = 1;
00389     info.bBitsPerPixel = 1;
00390     info.hInstance     = hInst;
00391     info.dwResGroupId  = -1;
00392     info.hColorBmp     = 0;
00393 
00394     return CreateCursorIconIndirect( 0, &info, lpANDbits, lpXORbits, FALSE);
00395 }
00396 //******************************************************************************
00397 //******************************************************************************
00398 BOOL WIN32API DestroyCursor( HCURSOR hCursor)
00399 {
00400     dprintf(("USER32:  DestroyCursor %x", hCursor));
00401     return CURSORICON_Destroy( hCursor, CID_WIN32 );
00402 }
00403 //******************************************************************************
00404 //******************************************************************************
00405 HCURSOR WIN32API GetCursor(void)
00406 {
00407     dprintf2(("USER32: GetCursor"));
00408     if(hActiveCursorPM && hActiveCursorPM != OSLibWinQueryPointer()) {
00409        dprintf(("Another app changed mouse cursor"));
00410        hActiveCursorPM = hActiveCursor = 0; 
00411     }
00412     return hActiveCursor;
00413 }
00414 //******************************************************************************
00415 //******************************************************************************
00416 HCURSOR WIN32API SetCursor( HCURSOR hCursor)
00417 {
00418   HCURSOR hOldCursor;
00419 
00420     dprintf(("USER32: SetCursor %x (prev %x)", hCursor, hActiveCursor));
00421     GetCursor();
00422     if (hCursor == hActiveCursor) return hActiveCursor;  /* No change */
00423 
00424     hOldCursor = hActiveCursor;
00425     hActiveCursor = hCursor;
00426 
00427 #ifdef __WIN32OS2__
00428     hCursor = ObjGetHandleData(hCursor, USEROBJ_CURSORICON);
00429     if(hCursor == -1) {
00430         dprintf(("ERROR: Invalid cursor/icon!"));
00431         return 0;
00432     }
00433 #endif
00434 
00435     CURSORICONINFO *iconinfo = (CURSORICONINFO *)GlobalLock((HGLOBAL)hCursor);
00436     if (!iconinfo) {
00437         dprintf(("ERROR: Invalid cursor!"));
00438         return 0;
00439     }
00440     if(!iconinfo->hColorBmp) {
00441         dprintf(("SetCursor: invalid os/2 pointer handle!!"));
00442     }
00443 
00444     dprintf2(("OSLibWinSetPointer %x", iconinfo->hColorBmp));
00445     if(OSLibWinSetPointer(iconinfo->hColorBmp) == FALSE) {
00446         dprintf(("OSLibWinSetPointer %x returned FALSE!!", iconinfo->hColorBmp));
00447     }
00448     hActiveCursorPM = iconinfo->hColorBmp;
00449     GlobalUnlock(hCursor);
00450 
00451     return hOldCursor;
00452 }
00453 //******************************************************************************
00454 //******************************************************************************
00455 BOOL WIN32API GetCursorPos( PPOINT lpPoint)
00456 {
00457     dprintf2(("USER32: GetCursorPos %x", lpPoint));
00458 
00459     if (!lpPoint) return FALSE;
00460 
00461     if (OSLibWinQueryPointerPos(lpPoint)) //POINT == POINTL
00462     {
00463         mapScreenPoint((OSLIBPOINT*)lpPoint);
00464         return TRUE;
00465     }
00466     else return FALSE;
00467 }
00468 //******************************************************************************
00469 //******************************************************************************
00470 BOOL WIN32API SetCursorPos( int X, int Y)
00471 {
00472     dprintf(("USER32: SetCursorPos %d %d", X,Y));
00473     return OSLibWinSetPointerPos(X, mapScreenY(Y));
00474 }
00475 //******************************************************************************
00476 //******************************************************************************
00477 BOOL WIN32API ClipCursor(const RECT * lpRect)
00478 {
00479     if(lpRect) {
00480          dprintf(("USER32: ClipCursor (%d,%d)(%d,%d)", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom));
00481     }
00482     else dprintf(("USER32: ClipCursor NULL"));
00483     return OSLibWinClipCursor(lpRect);
00484 }
00485 //******************************************************************************
00486 //******************************************************************************
00487 BOOL WIN32API GetClipCursor( LPRECT lpRect)
00488 {
00489     dprintf(("USER32: GetClipCursor %x", lpRect));
00490     return OSLibWinGetClipCursor(lpRect);
00491 }
00492 //******************************************************************************
00493 //******************************************************************************
00494 /*****************************************************************************
00495  * Name      : BOOL WIN32API SetSystemCursor
00496  * Purpose   : The SetSystemCursor function replaces the contents of the system
00497  *             cursor specified by dwCursorId with the contents of the cursor
00498  *             specified by hCursor, and then destroys hCursor. This function
00499  *             lets an application customize the system cursors.
00500  * Parameters: HCURSOR  hCursor    set specified system cursor to this cursor's
00501  *                                 contents, then destroy this
00502  *             DWORD    dwCursorID system cursor specified by its identifier
00503  * Variables :
00504  * Result    : If the function succeeds, the return value is TRUE.
00505  *             If the function fails, the return value is FALSE. To get extended
00506  *             error information, call GetLastError.
00507  * Remark    :
00508  * Status    : UNTESTED STUB
00509  *
00510  * Author    : Patrick Haller [Thu, 1998/02/26 11:55]
00511  *****************************************************************************/
00512 BOOL WIN32API SetSystemCursor(HCURSOR hCursor, DWORD dwCursorId)
00513 {
00514   dprintf(("USER32:SetSystemCursor (%08xh,%08x) not supported.\n",
00515          hCursor,
00516          dwCursorId));
00517 
00518   return DestroyCursor(hCursor);
00519 }
00520 //******************************************************************************
00521 //******************************************************************************
00522 INT OPEN32API __ShowCursor(BOOL bShow);
00523 
00524 inline INT _ShowCursor (BOOL bShow)
00525 {
00526  INT yyrc;
00527  USHORT sel = RestoreOS2FS();
00528 
00529     yyrc = __ShowCursor(bShow);
00530     SetFS(sel);
00531 
00532     return yyrc;
00533 }
00534 //******************************************************************************
00535 static int cursorshowcnt = 0;
00536 //******************************************************************************
00537 void RestoreCursor()
00538 {
00539     dprintf2(("USER32: RestoreCursor %d", cursorshowcnt));
00540     while(cursorshowcnt != 0)
00541     {
00542         if(cursorshowcnt > 0 )
00543         {
00544             ShowCursor(FALSE);
00545         }
00546         else
00547         {
00548             ShowCursor(TRUE);
00549         }
00550     }
00551 }
00552 //******************************************************************************
00553 //******************************************************************************
00554 int WIN32API ShowCursor(BOOL bShow)
00555 {
00556     dprintf2(("USER32: ShowCursor %d", bShow));
00557     cursorshowcnt = cursorshowcnt + ((bShow) ? 1 : -1);
00558     return _ShowCursor(bShow);
00559 }
00560 /***********************************************************************
00561  *           CreateCursorIconIndirect
00562  */
00563 static HGLOBAL CreateCursorIconIndirect( HINSTANCE hInstance,
00564                                          CURSORICONINFO *info,
00565                                          LPCVOID lpANDbits,
00566                                          LPCVOID lpXORbits, BOOL fIcon)
00567 {
00568     HGLOBAL handle;
00569     char *ptr;
00570     int sizeAnd, sizeXor;
00571 #ifdef __WIN32OS2__
00572     BITMAP bmpXor, bmpAnd;
00573 #endif
00574 
00575     if (!lpXORbits || !lpANDbits || info->bPlanes != 1) return 0;
00576     info->nWidthBytes = BITMAP_GetWidthBytes(info->nWidth,info->bBitsPerPixel);
00577     sizeXor = info->nHeight * info->nWidthBytes;
00578     sizeAnd = info->nHeight * BITMAP_GetWidthBytes( info->nWidth, 1 );
00579     if (!(handle = GlobalAlloc( GMEM_MOVEABLE,
00580                                 sizeof(CURSORICONINFO) + sizeXor + sizeAnd)))
00581         return 0;
00582     ptr = (char *)GlobalLock( handle );
00583     memcpy( ptr, info, sizeof(*info) );
00584     memcpy( ptr + sizeof(CURSORICONINFO), lpANDbits, sizeAnd );
00585     memcpy( ptr + sizeof(CURSORICONINFO) + sizeAnd, lpXORbits, sizeXor );
00586 #ifdef __WIN32OS2__
00587     bmpAnd.bmType       = 0;
00588     bmpAnd.bmWidth      = info->nWidth;
00589     bmpAnd.bmHeight     = info->nHeight;
00590     bmpAnd.bmWidthBytes = BITMAP_GetWidthBytes(info->nWidth, 1);
00591     bmpAnd.bmPlanes     = info->bPlanes;
00592     bmpAnd.bmBitsPixel  = 1;
00593     bmpAnd.bmBits       = NULL;
00594 
00595     bmpXor.bmType       = 0;
00596     bmpXor.bmWidth      = info->nWidth;
00597     bmpXor.bmHeight     = info->nHeight;
00598     bmpXor.bmWidthBytes = info->nWidthBytes;
00599     bmpXor.bmPlanes     = info->bPlanes;
00600     bmpXor.bmBitsPixel  = info->bBitsPerPixel;
00601     bmpXor.bmBits       = NULL;
00602     ((CURSORICONINFO *)ptr)->hColorBmp = 
00603           OSLibWinCreatePointer(info, (char *)lpANDbits, (LPBITMAP_W)&bmpAnd, (char *)lpXORbits, (LPBITMAP_W)&bmpXor, fIcon == FALSE);
00604 #endif
00605     GlobalUnlock( handle );
00606 
00607 #ifdef __WIN32OS2__
00608     HICON hIcon;
00609     if(ObjAllocateHandle(&hIcon, (DWORD)handle, USEROBJ_CURSORICON) == FALSE) {
00610         GlobalFree(handle);
00611         dprintf(("ERROR: CreateCursorIconIndirect ObjAllocateHandle failed!!"));
00612         return 0;
00613     }
00614     dprintf(("USER32: CreateCursorIconIndirect returned %x", hIcon));
00615     return hIcon;
00616 #else
00617     return handle;
00618 #endif
00619 }
00620 /**********************************************************************
00621  *          CURSORICON_Load
00622  *
00623  * Load a cursor or icon from resource or file.
00624  */
00625 HGLOBAL CURSORICON_Load( HINSTANCE hInstance, LPCWSTR name,
00626                          INT width, INT height, INT colors,
00627                          BOOL fCursor, UINT loadflags )
00628 {
00629     HANDLE handle = 0, h = 0;
00630     HANDLE hRsrc;
00631     CURSORICONDIR *dir;
00632     CURSORICONDIRENTRY *dirEntry;
00633     LPBYTE bits;
00634 
00635 #ifdef __WIN32OS2__
00636     //TODO: Can system cursors be loaded by name??? (#xxx)
00637     if (fCursor && hInstance == NULL && !HIWORD(name))
00638     {
00639         HCURSOR hCursor = OSLibWinQuerySysPointer((ULONG)name, width, height);
00640         if(hCursor)
00641         {
00642             /* If shared icon, check whether it was already loaded */
00643             if ((loadflags & LR_SHARED)
00644                 && (h = CURSORICON_FindSharedIcon( -1, hCursor ) ) != 0 )
00645             {
00646                 dprintf(("Found icon/cursor in cache; returned old handle %x", h));
00647                 return h;
00648             }
00649 
00650             HANDLE hObj = GlobalAlloc( GMEM_MOVEABLE,  sizeof(CURSORICONINFO));
00651             if (!hObj)
00652             {
00653                 DebugInt3();
00654                 return 0;
00655             }
00656             CURSORICONINFO *info;
00657 
00658             info = (CURSORICONINFO *)GlobalLock( hObj );
00659             info->ptHotSpot.x   = 0;
00660             info->ptHotSpot.y   = 0;
00661             info->nWidth        = width;
00662             info->nHeight       = height;
00663             info->nWidthBytes   = width*height/8;
00664             info->bPlanes       = 1;
00665             info->bBitsPerPixel = 1;
00666             info->hColorBmp     = hCursor;
00667             info->hInstance     = -1;
00668             info->dwResGroupId  = -1;
00669 
00670             HICON hIcon;
00671             if(ObjAllocateHandle(&hIcon, (DWORD)hObj, USEROBJ_CURSORICON) == FALSE) {
00672                GlobalUnlock( hObj );
00673                GlobalFree(hObj);
00674                dprintf(("ERROR: CURSORICON_Load ObjAllocateHandle failed!!"));
00675                return 0;
00676             }
00677 
00678             if (loadflags & LR_SHARED )
00679                 CURSORICON_AddSharedIcon( -1, hCursor, -1, hIcon );
00680 
00681             GlobalUnlock( hObj );
00682 
00683             return hIcon;
00684         }
00685     }
00686 #endif
00687     if ( loadflags & LR_LOADFROMFILE )    /* Load from file */
00688     {
00689         LPBYTE *ptr;
00690 
00691         if (!CURSORICON_SimulateLoadingFromResourceW((LPWSTR)name, fCursor, &dir, &ptr))
00692             return 0;
00693         if (fCursor)
00694             dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestCursor(dir, width, height, 1);
00695         else
00696             dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(dir, width, height, colors);
00697         bits = ptr[dirEntry->wResId-1];
00698         h = CURSORICON_CreateFromResource( 0, -1, 0, bits, dirEntry->dwBytesInRes,
00699                                            !fCursor, 0x00030000, width, height, loadflags);
00700 
00701         HeapFree( GetProcessHeap(), 0, dir );
00702         HeapFree( GetProcessHeap(), 0, ptr );
00703     }
00704     else  /* Load from resource */
00705     {
00706         HANDLE hGroupRsrc;
00707         WORD wResId;
00708         DWORD dwBytesInRes;
00709         BOOL  bIsGroup = TRUE;
00710 
00711         /* Get directory resource ID */
00712         if (!hInstance)
00713         {
00714             hRsrc = FindResourceW(hInstanceUser32, name, fCursor ? RT_CURSORW : RT_ICONW);
00715             if(!hRsrc) {
00716                 hRsrc = FindResourceW(hInstanceUser32, name, fCursor ? RT_GROUP_CURSORW : RT_GROUP_ICONW);
00717             }
00718             else bIsGroup = FALSE;
00719 
00720             if(!hRsrc)  return 0;
00721 
00722             hInstance = hInstanceUser32;
00723         }
00724         else {
00725             hRsrc = FindResourceW(hInstance, name, fCursor ? RT_GROUP_CURSORW : RT_GROUP_ICONW);
00726             if(!hRsrc)  return 0;
00727         }
00728         hGroupRsrc = hRsrc;
00729 
00730         if(bIsGroup) {
00731             /* Find the best entry in the directory */
00732 
00733             if (!(handle = LoadResource( hInstance, hRsrc ))) return 0;
00734             if (!(dir = (CURSORICONDIR*)LockResource( handle ))) return 0;
00735 
00736             if (fCursor)
00737                 dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestCursor( dir,
00738                                                                   width, height, 1);
00739             else
00740                 dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon( dir,
00741                                                            width, height, colors );
00742             if (!dirEntry) return 0;
00743             wResId = dirEntry->wResId;
00744             dwBytesInRes = dirEntry->dwBytesInRes;
00745             FreeResource( handle );
00746 
00747             /* Load the resource */
00748             if (!(hRsrc = FindResourceW(hInstance,MAKEINTRESOURCEW(wResId),
00749                                       fCursor ? RT_CURSORW : RT_ICONW ))) return 0;
00750         }
00751 
00752         /* If shared icon, check whether it was already loaded */
00753         if ((loadflags & LR_SHARED)
00754             && (h = CURSORICON_FindSharedIcon( hInstance, hRsrc ) ) != 0 )
00755         {
00756             dprintf(("Found icon/cursor in cache; returned old handle %x", h));
00757             return h;
00758         }
00759 
00760         if (!(handle = LoadResource( hInstance, hRsrc ))) return 0;
00761         bits = (LPBYTE)LockResource( handle );
00762         h = CURSORICON_CreateFromResource( hInstance, (DWORD)name, 0, bits, dwBytesInRes,
00763                                            !fCursor, 0x00030000, width, height, loadflags);
00764         FreeResource( handle );
00765 
00766         /* If shared icon, add to icon cache */
00767 
00768         if ( h && (loadflags & LR_SHARED) )
00769             CURSORICON_AddSharedIcon( hInstance, hRsrc, hGroupRsrc, h );
00770 
00771     }
00772 
00773     return h;
00774 }
00775 
00776 /*********************************************************************
00777  * The main purpose of this function is to create fake resource directory
00778  * and fake resource entries. There are several reasons for this:
00779  *  -   CURSORICONDIR and CURSORICONFILEDIR differ in sizes and their
00780  *              fields
00781  *  There are some "bad" cursor files which do not have
00782  *      bColorCount initialized but instead one must read this info
00783  *      directly from corresponding DIB sections
00784  * Note: wResId is index to array of pointer returned in ptrs (origin is 1)
00785  */
00786 BOOL CURSORICON_SimulateLoadingFromResourceW( LPWSTR filename, BOOL fCursor,
00787                                               CURSORICONDIR **res, LPBYTE **ptr)
00788 {
00789     LPBYTE    _free;
00790     CURSORICONFILEDIR *bits;
00791     int        entries, size, i;
00792     HANDLE     hMapping = 0;
00793 
00794     *res = NULL;
00795     *ptr = NULL;
00796 
00797     hMapping = VIRTUAL_MapFileW( filename, (LPVOID *)&bits, TRUE);
00798     if(hMapping == INVALID_HANDLE_VALUE)
00799             return FALSE;
00800 
00801     /* FIXME: test for inimated icons
00802      * hack to load the first icon from the *.ani file
00803      */
00804     if ( *(LPDWORD)bits==0x46464952 ) /* "RIFF" */
00805     {
00806         LPBYTE pos = (LPBYTE) bits;
00807         dprintf(("Animated icons not correctly implemented! %p \n", bits));
00808 
00809         for (;;)
00810         {
00811             if (*(LPDWORD)pos==0x6e6f6369)      /* "icon" */
00812             {
00813                 dprintf(("icon entry found! %p\n", bits));
00814                 pos+=4;
00815                 if ( !*(LPWORD) pos==0x2fe)       /* iconsize */
00816                 {
00817                     goto fail;
00818                 }
00819                 bits=(CURSORICONFILEDIR*)(pos+4);
00820                 dprintf(("icon size ok. offset=%p \n", bits));
00821                 break;
00822             }
00823             pos+=2;
00824             if (pos>=(LPBYTE)bits+766) goto fail;
00825         }
00826     }
00827     if (!(entries = bits->idCount)) goto fail;
00828     size = sizeof(CURSORICONDIR) + sizeof(CURSORICONDIRENTRY) * (entries - 1);
00829     _free = (LPBYTE) size;
00830 
00831     for (i=0; i < entries; i++)
00832       size += bits->idEntries[i].dwDIBSize + (fCursor ? sizeof(POINT16): 0);
00833 
00834     if (!(*ptr = (LPBYTE *)HeapAlloc( GetProcessHeap(), 0,
00835                             entries * sizeof (CURSORICONDIRENTRY*)))) goto fail;
00836     if (!(*res = (CURSORICONDIR *)HeapAlloc( GetProcessHeap(), 0, size))) goto fail;
00837 
00838     _free = (LPBYTE)(*res) + (int)_free;
00839     memcpy((*res), bits, 6);
00840     for (i=0; i<entries; i++)
00841     {
00842       ((LPBYTE*)(*ptr))[i] = _free;
00843       if (fCursor) {
00844         (*res)->idEntries[i].ResInfo.cursor.wWidth=bits->idEntries[i].bWidth;
00845         (*res)->idEntries[i].ResInfo.cursor.wHeight=bits->idEntries[i].bHeight;
00846         ((LPPOINT16)_free)->x=bits->idEntries[i].xHotspot;
00847         ((LPPOINT16)_free)->y=bits->idEntries[i].yHotspot;
00848         _free+=sizeof(POINT16);
00849       }
00850       else {
00851         (*res)->idEntries[i].ResInfo.icon.bWidth=bits->idEntries[i].bWidth;
00852         (*res)->idEntries[i].ResInfo.icon.bHeight=bits->idEntries[i].bHeight;
00853         (*res)->idEntries[i].ResInfo.icon.bColorCount = bits->idEntries[i].bColorCount;
00854       }
00855       (*res)->idEntries[i].wPlanes=1;
00856       (*res)->idEntries[i].wBitCount = ((LPBITMAPINFOHEADER)((LPBYTE)bits +
00857                                                    bits->idEntries[i].dwDIBOffset))->biBitCount;
00858       (*res)->idEntries[i].dwBytesInRes = bits->idEntries[i].dwDIBSize;
00859       (*res)->idEntries[i].wResId=i+1;
00860 
00861       memcpy(_free,(LPBYTE)bits +bits->idEntries[i].dwDIBOffset,
00862              (*res)->idEntries[i].dwBytesInRes);
00863       _free += (*res)->idEntries[i].dwBytesInRes;
00864     }
00865     UnmapViewOfFile( bits );
00866     CloseHandle(hMapping);
00867     return TRUE;
00868 
00869 fail:
00870     if (*res) HeapFree( GetProcessHeap(), 0, *res );
00871     if (*ptr) HeapFree( GetProcessHeap(), 0, *ptr );
00872 
00873     UnmapViewOfFile( bits );
00874     CloseHandle(hMapping);
00875     return FALSE;
00876 }
00877 
00878 /**********************************************************************
00879  *      CURSORICON_CreateFromResource
00880  *
00881  * Create a cursor or icon from in-memory resource template.
00882  *
00883  * FIXME: Convert to mono when cFlag is LR_MONOCHROME. Do something
00884  *        with cbSize parameter as well.
00885  */
00886 static HGLOBAL CURSORICON_CreateFromResource( HINSTANCE hInstance, DWORD dwResGroupId, HGLOBAL hObj, LPBYTE bits,
00887                         UINT cbSize, BOOL bIcon, DWORD dwVersion,
00888                         INT width, INT height, UINT loadflags )
00889 {
00890     int sizeAnd, sizeXor;
00891     HBITMAP hAndBits = 0, hXorBits = 0; /* error condition for later */
00892     BITMAP bmpXor, bmpAnd;
00893     POINT16 hotspot;
00894     BITMAPINFO *bmi;
00895     HDC hdc = 0;
00896     BOOL DoStretch;
00897     INT size, colortablesize, bwsize, colorsize;
00898 
00899     hotspot.x = ICON_HOTSPOT;
00900     hotspot.y = ICON_HOTSPOT;
00901 
00902     dprintf2(("CURSORICON_CreateFromResource %x %x %x %x %d", hInstance, dwResGroupId, hObj, bits, cbSize));
00903 
00904     if (dwVersion == 0x00020000)
00905     {
00906         dprintf(("CURSORICON_CreateFromResource 2.xx resources are not supported"));
00907         return 0;
00908     }
00909 
00910     if (bIcon) {
00911         bmi = (BITMAPINFO *)bits;
00912     }
00913     else /* get the hotspot */
00914     {
00915         POINT16 *pt = (POINT16 *)bits;
00916         hotspot = *pt;
00917         bmi = (BITMAPINFO *)(pt + 1);
00918     }
00919     size = DIB_BitmapInfoSize(bmi, DIB_RGB_COLORS);
00920 
00921     if (!width) width = bmi->bmiHeader.biWidth;
00922     if (!height) height = bmi->bmiHeader.biHeight/2;
00923 
00924     DoStretch = (bmi->bmiHeader.biHeight/2 != height) || (bmi->bmiHeader.biWidth != width);
00925 
00926     colorsize = DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight/2, bmi->bmiHeader.biBitCount);
00927     bwsize    = (bmi->bmiHeader.biWidth * bmi->bmiHeader.biHeight/2)/8;
00928 
00929     /* Check bitmap header */
00930     if((bmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) &&
00931        (bmi->bmiHeader.biSize != sizeof(BITMAPINFOHEADER)  ||
00932         bmi->bmiHeader.biCompression != BI_RGB) )
00933     {
00934         return 0;
00935     }
00936 
00937 #ifdef __WIN32OS2__
00938     if( (hdc = CreateCompatibleDC( 0 )) )
00939 #else
00940     if( (hdc = GetDC( 0 )) )
00941 #endif
00942     {
00943         BITMAPINFO* pInfo;
00944 
00945         /* Make sure we have room for the monochrome bitmap later on.
00946          * Note that BITMAPINFOINFO and BITMAPCOREHEADER are the same
00947          * up to and including the biBitCount. In-memory icon resource
00948          * format is as follows:
00949          *
00950          *   BITMAPINFOHEADER   icHeader  // DIB header
00951          *   RGBQUAD         icColors[]   // Color table
00952          *   BYTE            icXOR[]      // DIB bits for XOR mask
00953          *   BYTE            icAND[]      // DIB bits for AND mask
00954          */
00955 
00956         if ((pInfo = (BITMAPINFO *)HeapAlloc( GetProcessHeap(), 0,
00957                                               max(size, sizeof(BITMAPINFOHEADER) + 2*sizeof(RGBQUAD)))))
00958         {
00959             memcpy( pInfo, bmi, size );
00960             pInfo->bmiHeader.biHeight /= 2;
00961 
00962             /* Create the XOR bitmap */
00963             if (DoStretch)
00964             {
00965                 if(bIcon)
00966                 {
00967                     hXorBits = CreateCompatibleBitmap(hdc, width, height);
00968                 }
00969                 else
00970                 {
00971                     hXorBits = CreateBitmap(width, height, 1, 1, NULL);
00972                 }
00973                 if(hXorBits)
00974                 {
00975                     HBITMAP hOld;
00976                     HDC hMem = CreateCompatibleDC(hdc);
00977                     BOOL res;
00978 
00979                     if (hMem) {
00980                         hOld = SelectObject(hMem, hXorBits);
00981                         res = StretchDIBits(hMem, 0, 0, width, height, 0, 0,
00982                                             bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight/2,
00983                                             (char*)bmi + size, pInfo, DIB_RGB_COLORS, SRCCOPY);
00984                         SelectObject(hMem, hOld);
00985                         DeleteDC(hMem);
00986                     }
00987                     else res = FALSE;
00988                     if (!res) {
00989                         DeleteObject(hXorBits);
00990                         hXorBits = 0;
00991                     }
00992                 }
00993             }
00994             else
00995             {
00996                 hXorBits = CreateDIBitmap(hdc, &pInfo->bmiHeader,
00997                                           CBM_INIT, (char*)bmi + size, pInfo, DIB_RGB_COLORS );
00998             }
00999             if( hXorBits )
01000             {
01001                 char* xbits = (char *)bmi + size + DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
01002                                                                         bmi->bmiHeader.biHeight,
01003                                                                         bmi->bmiHeader.biBitCount) / 2;
01004 
01005                 pInfo->bmiHeader.biBitCount = 1;
01006                 if (pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
01007                 {
01008                     RGBQUAD *rgb = pInfo->bmiColors;
01009 
01010                     pInfo->bmiHeader.biClrUsed = pInfo->bmiHeader.biClrImportant = 2;
01011                     rgb[0].rgbBlue = rgb[0].rgbGreen = rgb[0].rgbRed = 0x00;
01012                     rgb[1].rgbBlue = rgb[1].rgbGreen = rgb[1].rgbRed = 0xff;
01013                     rgb[0].rgbReserved = rgb[1].rgbReserved = 0;
01014                 }
01015                 else
01016                 {
01017                     RGBTRIPLE *rgb = (RGBTRIPLE *)(((BITMAPCOREHEADER *)pInfo) + 1);
01018 
01019                     rgb[0].rgbtBlue = rgb[0].rgbtGreen = rgb[0].rgbtRed = 0x00;
01020                     rgb[1].rgbtBlue = rgb[1].rgbtGreen = rgb[1].rgbtRed = 0xff;
01021                 }
01022 
01023                 /* Create the AND bitmap */
01024                 if (DoStretch)
01025                 {
01026                     if ((hAndBits = CreateBitmap(width, height, 1, 1, NULL)))
01027                     {
01028                         HBITMAP hOld;
01029                         HDC hMem = CreateCompatibleDC(hdc);
01030                         BOOL res;
01031 
01032                         if (hMem) {
01033                             hOld = SelectObject(hMem, hAndBits);
01034 //SvL: This also doesn't work as StretchDIBits doesn't handle 1bpp bitmaps correctly
01035 //--------->>> hack alert!
01036 #if 1
01037                             HBITMAP hBmp, hOld1;
01038                             HDC hMem1;
01039 
01040                             hMem1 = CreateCompatibleDC(hdc);
01041 
01042                             int linewidth = BITMAP_GetWidthBytes(pInfo->bmiHeader.biWidth, 1);
01043 
01044                             char *newpix = (char *)malloc(linewidth*pInfo->bmiHeader.biHeight);
01045 
01046                             newpix += ((pInfo->bmiHeader.biHeight-1)*linewidth);
01047 
01048                             if(cbSize - size - colorsize - bwsize == bwsize)
01049                             {//this means an AND and XOR mask is present (interleaved; and/xor)
01050                                 for(int i=0;i<pInfo->bmiHeader.biHeight;i++) {
01051                                     memcpy(newpix, xbits, linewidth);
01052                                     newpix -= linewidth;
01053                                     xbits  += linewidth*2;
01054                                 }
01055                             }
01056                             else {
01057                                 for(int i=0;i<pInfo->bmiHeader.biHeight;i++) {
01058                                     memcpy(newpix, xbits, linewidth);
01059                                     newpix -= linewidth;
01060                                     xbits  += linewidth;
01061                                 }
01062                             }
01063                             newpix += linewidth;
01064                             hBmp = CreateBitmap(pInfo->bmiHeader.biWidth, pInfo->bmiHeader.biHeight, 1, 1, newpix);
01065                             free(newpix);
01066 
01067                             hOld1 = SelectObject(hMem1, hBmp);
01068 
01069                             res = StretchBlt(hMem, 0, 0, width, height, hMem1,  0, 0, pInfo->bmiHeader.biWidth, pInfo->bmiHeader.biHeight, SRCCOPY);
01070 
01071                             SelectObject(hMem1, hOld1);
01072                             DeleteObject(hBmp);
01073                             DeleteDC(hMem1);
01074 
01075 
01076 #else
01077                             res = StretchDIBits(hMem, 0, 0, width, height, 0, 0,
01078                                                 pInfo->bmiHeader.biWidth, pInfo->bmiHeader.biHeight,
01079                                                 xbits, pInfo, DIB_RGB_COLORS, SRCCOPY);
01080 #endif
01081                             SelectObject(hMem, hOld);
01082                             DeleteDC(hMem);
01083                         }
01084                         else res = FALSE;
01085                         if (!res) {
01086                             DeleteObject(hAndBits);
01087                             hAndBits = 0;
01088                         }
01089                     }
01090                 }
01091                 else {
01092 //SvL: Must use CreateBitmap here as CreateDIBitmap converts data to 8bpp (GetObjectA info -> 8 bpp)
01093 #if 1
01094                     int linewidth = BITMAP_GetWidthBytes(width, 1);
01095 
01096                     char *newpix = (char *)malloc(linewidth*height);
01097 
01098                     newpix += ((height-1)*linewidth);
01099 
01100                     if(cbSize - size - colorsize - bwsize == bwsize)
01101                     {//this means an AND and XOR mask is present (interleaved; and/xor)
01102                         for(int i=0;i<height;i++) {
01103                             memcpy(newpix, xbits, linewidth);
01104                             newpix -= linewidth;
01105                             xbits  += linewidth*2;
01106                         }
01107                     }
01108                     else {
01109                         for(int i=0;i<height;i++) {
01110                             memcpy(newpix, xbits, linewidth);
01111                             newpix -= linewidth;
01112                             xbits  += linewidth;
01113                         }
01114                     }
01115                     newpix += linewidth;
01116                     hAndBits = CreateBitmap(width, height, 1, 1, newpix);
01117 
01118                     free(newpix);
01119 
01120 #else
01121                     hAndBits = CreateDIBitmap(hdc, &pInfo->bmiHeader,
01122                                               CBM_INIT, xbits, pInfo, DIB_RGB_COLORS );
01123 #endif
01124                 }
01125                 if( !hAndBits )
01126                     DeleteObject( hXorBits );
01127              }
01128              HeapFree( GetProcessHeap(), 0, pInfo );
01129         }
01130 #ifdef __WIN32OS2__
01131         DeleteDC(hdc );
01132 #else
01133         ReleaseDC( 0, hdc );
01134 #endif
01135     }
01136 
01137     if( !hXorBits || !hAndBits )
01138     {
01139         dprintf(("\tunable to create an icon bitmap."));
01140         return 0;
01141     }
01142 
01143     /* Now create the CURSORICONINFO structure */
01144     GetObjectA( hXorBits, sizeof(bmpXor), &bmpXor );
01145     GetObjectA( hAndBits, sizeof(bmpAnd), &bmpAnd );
01146     colortablesize = 0;
01147 
01148     if(bmpXor.bmBitsPixel <= 8) {
01149          colortablesize = sizeof(RGBQUAD)*(1<<bmpXor.bmBitsPixel);
01150          sizeXor = bmpXor.bmHeight * bmpXor.bmWidthBytes + colortablesize;
01151     }
01152     else sizeXor = bmpXor.bmHeight * bmpXor.bmWidthBytes;
01153 
01154     sizeAnd = bmpAnd.bmHeight * bmpAnd.bmWidthBytes;
01155 
01156     if (hObj) hObj = GlobalReAlloc( hObj,
01157              sizeof(CURSORICONINFO) + sizeXor + sizeAnd, GMEM_MOVEABLE );
01158     if (!hObj) hObj = GlobalAlloc( GMEM_MOVEABLE,
01159              sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
01160     if (hObj)
01161     {
01162         CURSORICONINFO *info;
01163 
01164         info = (CURSORICONINFO *)GlobalLock( hObj );
01165         info->ptHotSpot.x   = hotspot.x;
01166         info->ptHotSpot.y   = hotspot.y;
01167         info->nWidth        = bmpXor.bmWidth;
01168         info->nHeight       = bmpXor.bmHeight;
01169         info->nWidthBytes   = bmpXor.bmWidthBytes;
01170         info->bPlanes       = bmpXor.bmPlanes;
01171         info->bBitsPerPixel = bmpXor.bmBitsPixel;
01172         info->hInstance     = hInstance;
01173         info->dwResGroupId  = dwResGroupId;
01174         info->hColorBmp     = 0;
01175 
01176         /* Transfer the bitmap bits to the CURSORICONINFO structure */
01177         GetBitmapBits( hAndBits, sizeAnd, (char *)(info + 1));
01178 
01179         if(bmpXor.bmBitsPixel > 1)
01180         {
01181             BITMAPINFO* pInfo = (BITMAPINFO *)malloc(sizeof(BITMAPINFO)+colortablesize+3*sizeof(DWORD)); //+ extra space for > 8bpp images
01182             HBITMAP oldbmp;
01183 
01184             hdc = CreateCompatibleDC(0);
01185 
01186             memset(pInfo, 0, sizeof(BITMAPINFO)+colortablesize+3*sizeof(DWORD));
01187             pInfo->bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
01188             pInfo->bmiHeader.biPlanes   = info->bPlanes;
01189             pInfo->bmiHeader.biBitCount = info->bBitsPerPixel;
01190 
01191             GetDIBits(hdc, hXorBits, 0, bmpXor.bmHeight, (char *)(info + 1) + sizeAnd + colortablesize, pInfo, DIB_RGB_COLORS);
01192             if(colortablesize) {
01193                 memcpy((char *)(info + 1) + sizeAnd, (char *)&pInfo->bmiHeader + pInfo->bmiHeader.biSize, colortablesize);
01194             }
01195 
01196             DeleteDC(hdc);
01197             free(pInfo);
01198         }
01199         else {
01200             GetBitmapBits( hXorBits, sizeXor, (char *)(info + 1) + sizeAnd);
01201         }
01202         info->hColorBmp = OSLibWinCreatePointer(info, (char*)(info + 1), (LPBITMAP_W)&bmpAnd, (char*)(info + 1) + sizeAnd, (LPBITMAP_W)&bmpXor, bIcon == FALSE);
01203 
01204         dprintf(("Create cursor/icon %x with OS/2 pointer handle %x", hObj, info->hColorBmp));
01205         GlobalUnlock( hObj );
01206     }
01207 
01208     DeleteObject( hAndBits );
01209     DeleteObject( hXorBits );
01210 
01211 #ifdef __WIN32OS2__
01212     if(hObj) {
01213         HICON hIcon;
01214         if(ObjAllocateHandle(&hIcon, (DWORD)hObj, USEROBJ_CURSORICON) == FALSE) {
01215             GlobalFree(hObj);
01216             dprintf(("ERROR: CURSORICON_Load ObjAllocateHandle failed!!"));
01217             return 0;
01218         }
01219         return hIcon;
01220     }
01221 #endif
01222     return hObj;
01223 }
01224 
01225 /**********************************************************************
01226  *      CURSORICON_Destroy   (USER.610)
01227  *
01228  * This routine is actually exported from Win95 USER under the name
01229  * DestroyIcon32 ...  The behaviour implemented here should mimic
01230  * the Win95 one exactly, especially the return values, which
01231  * depend on the setting of various flags.
01232  */
01233 WORD WIN32API CURSORICON_Destroy( HGLOBAL handle, UINT flags )
01234 {
01235     WORD retv;
01236 
01237     /* Check whether destroying active cursor */
01238 
01239     if ( hActiveCursor == handle )
01240     {
01241         dprintf(("WARNING: Destroying active cursor!" ));
01242         SetCursor( 0 );
01243     }
01244 
01245 #ifdef __WIN32OS2__
01246     HICON hIcon = ObjGetHandleData(handle, USEROBJ_CURSORICON);
01247     if(hIcon == -1) {
01248         dprintf(("ERROR: Invalid cursor/icon!"));
01249         return 0;
01250     }
01251 #endif
01252 
01253     /* Try shared cursor/icon first */
01254     if ( !(flags & CID_NONSHARED) )
01255     {
01256         INT count = CURSORICON_DelSharedIcon( handle );
01257 
01258         if ( count != -1 )
01259             return (flags & CID_WIN32)? TRUE : (count == 0);
01260 
01261         /* FIXME: OEM cursors/icons should be recognized */
01262     }
01263     /* Now assume non-shared cursor/icon */
01264 
01265 #ifdef __WIN32OS2__
01266     CURSORICONINFO *iconinfo = (CURSORICONINFO *)GlobalLock((HGLOBAL)hIcon);
01267     if (!iconinfo) {
01268         dprintf(("ERROR: Invalid cursor!"));
01269         return 0;
01270     }
01271 
01272     if(iconinfo->hColorBmp) {
01273         OSLibWinDestroyPointer(iconinfo->hColorBmp);
01274     }
01275     GlobalUnlock(hIcon);
01276     retv = GlobalFree( hIcon );
01277     ObjFreeHandle(handle);
01278 
01279     return (flags & CID_RESOURCE)? retv : TRUE;
01280 #else
01281     retv = GlobalFree( handle );
01282     return (flags & CID_RESOURCE)? retv : TRUE;
01283 #endif
01284 }
01285 
01286 /***********************************************************************
01287  *           CURSORICON_Copy
01288  *
01289  * Make a copy of a cursor or icon.
01290  */
01291 static HGLOBAL CURSORICON_Copy(HGLOBAL handle)
01292 {
01293     char *ptrOld, *ptrNew;
01294     int size;
01295     HGLOBAL hNew;
01296 
01297     handle = ObjGetHandleData(handle, USEROBJ_CURSORICON);
01298     if(handle == -1) {
01299         dprintf(("ERROR: Invalid cursor/icon!"));
01300         return 0;
01301     }
01302 
01303     if (!(ptrOld = (char *)GlobalLock( handle ))) return 0;
01304 
01305     size = GlobalSize( handle );
01306     hNew = GlobalAlloc( GMEM_MOVEABLE, size );
01307 #ifdef __WIN32OS2__
01308     if(hNew == NULL) {
01309         dprintf(("ERROR: CURSORICON_Copy GlobalAlloc failed!!"));
01310         return NULL;
01311     }
01312 #endif
01313     ptrNew = (char *)GlobalLock( hNew );
01314     memcpy( ptrNew, ptrOld, size );
01315     GlobalUnlock( handle );
01316     GlobalUnlock( hNew );
01317 
01318 #ifdef __WIN32OS2__
01319     HICON hIcon;
01320     if(ObjAllocateHandle(&hIcon, (DWORD)hNew, USEROBJ_CURSORICON) == FALSE) {
01321         GlobalFree(hNew);
01322         dprintf(("ERROR: CURSORICON_Copy ObjAllocateHandle failed!!"));
01323         return 0;
01324     }
01325     return hIcon;
01326 #else
01327     return hNew;
01328 #endif
01329 }
01330 
01331 /*************************************************************************
01332  * CURSORICON_ExtCopy
01333  *
01334  * Copies an Image from the Cache if LR_COPYFROMRESOURCE is specified
01335  *
01336  * PARAMS
01337  *      Handle     [I] handle to an Image
01338  *      nType      [I] Type of Handle (IMAGE_CURSOR | IMAGE_ICON)
01339  *      iDesiredCX [I] The Desired width of the Image
01340  *      iDesiredCY [I] The desired height of the Image
01341  *      nFlags     [I] The flags from CopyImage
01342  *
01343  * RETURNS
01344  *     Success: The new handle of the Image
01345  *
01346  * NOTES
01347  *     LR_COPYDELETEORG and LR_MONOCHROME are currently not implemented.
01348  *     LR_MONOCHROME should be implemented by CURSORICON_CreateFromResource.
01349  *     LR_COPYFROMRESOURCE will only work if the Image is in the Cache.
01350  *
01351  *
01352  */
01353 HGLOBAL CURSORICON_ExtCopy(HGLOBAL Handle, UINT nType,
01354                            INT iDesiredCX, INT iDesiredCY,
01355                            UINT nFlags)
01356 {
01357     HGLOBAL hNew=0;
01358 
01359 #ifdef __WIN32OS2__
01360     HICON hIcon = ObjGetHandleData(Handle, USEROBJ_CURSORICON);
01361     if(hIcon == -1) {
01362         dprintf(("ERROR: Invalid cursor/icon!"));
01363         return 0;
01364     }
01365 
01366 #else
01367     if(Handle == 0)
01368     {
01369         return 0;
01370     }
01371 #endif
01372     /* Best Fit or Monochrome */
01373     if( (nFlags & LR_COPYFROMRESOURCE
01374         && (iDesiredCX > 0 || iDesiredCY > 0))
01375         || nFlags & LR_MONOCHROME)
01376     {
01377 #ifdef __WIN32OS2__
01378         ICONCACHE* pIconCache = CURSORICON_FindCache(hIcon);
01379 #else
01380         ICONCACHE* pIconCache = CURSORICON_FindCache(Handle);
01381 #endif
01382 
01383         /* Not Found in Cache, then do a straight copy
01384         */
01385         if(pIconCache == NULL)
01386         {
01387 #ifdef __WIN32OS2__
01388             hNew = CURSORICON_Copy(Handle);
01389 #else
01390             hNew = CURSORICON_Copy(0, Handle);
01391 #endif
01392             if(nFlags & LR_COPYFROMRESOURCE)
01393             {
01394                 dprintf(("WARNING: LR_COPYFROMRESOURCE: Failed to load from cache\n"));
01395             }
01396         }
01397         else
01398         {
01399             int iTargetCY = iDesiredCY, iTargetCX = iDesiredCX;
01400             LPBYTE pBits;
01401             HANDLE hMem;
01402             HRSRC hRsrc;
01403             DWORD dwBytesInRes;
01404             WORD wResId;
01405             DWORD dwResGroupId;
01406             HINSTANCE hInstance;
01407             CURSORICONINFO *iconinfo;
01408             CURSORICONDIR *pDir;
01409             CURSORICONDIRENTRY *pDirEntry;
01410             BOOL bIsIcon = (nType == IMAGE_ICON);
01411 
01412 #ifdef __WIN32OS2__
01413             iconinfo = (CURSORICONINFO *)GlobalLock( hIcon );
01414 #else
01415             iconinfo = (CURSORICONINFO *)GlobalLock( Handle );
01416 #endif
01417             if(iconinfo == NULL) {
01418                 dprintf(("ERROR: CURSORICON_ExtCopy invalid icon!"));
01419             }
01420             hInstance    = iconinfo->hInstance;
01421             dwResGroupId = iconinfo->dwResGroupId;
01422             GlobalUnlock( Handle );
01423             if(dwResGroupId == -1) {
01424                 //todo: if scaling is necessary..
01425                 dprintf(("WARNING: no resource associated with icon/cursor -> copy without scaling!"));
01426                 hNew = CURSORICON_Copy(Handle);
01427                 return hNew;
01428             }
01429 
01430             /* Completing iDesiredCX CY for Monochrome Bitmaps if needed
01431             */
01432             if(((nFlags & LR_MONOCHROME) && !(nFlags & LR_COPYFROMRESOURCE))
01433                 || (iDesiredCX == 0 && iDesiredCY == 0))
01434             {
01435                 iDesiredCY = GetSystemMetrics(bIsIcon ? SM_CYICON : SM_CYCURSOR);
01436                 iDesiredCX = GetSystemMetrics(bIsIcon ? SM_CXICON : SM_CXCURSOR);
01437             }
01438 
01439             /* Retreive the CURSORICONDIRENTRY
01440             */
01441             hRsrc = FindResourceW(hInstance, (LPWSTR)dwResGroupId, bIsIcon ? RT_GROUP_ICONW : RT_GROUP_CURSORW);
01442             if(!hRsrc)  {
01443                 goto notfound;
01444             }
01445 
01446             if (!(hMem = LoadResource( hInstance, hRsrc)))
01447             {
01448                 goto notfound;
01449             }
01450             if (!(pDir = (CURSORICONDIR*)LockResource( hMem )))
01451             {
01452                 goto notfound;
01453             }
01454 
01455             /* Find Best Fit
01456             */
01457             if(bIsIcon)
01458             {
01459                 pDirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(
01460                                 pDir, iDesiredCX, iDesiredCY, 256);
01461             }
01462             else
01463             {
01464                 pDirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestCursor(
01465                                 pDir, iDesiredCX, iDesiredCY, 1);
01466             }
01467 
01468             wResId = pDirEntry->wResId;
01469             dwBytesInRes = pDirEntry->dwBytesInRes;
01470             FreeResource(hMem);
01471 
01472             /* Get the Best Fit
01473             */
01474             if (!(hRsrc = FindResourceW(hInstance ,
01475                 MAKEINTRESOURCEW(wResId), bIsIcon ? RT_ICONW : RT_CURSORW)))
01476             {
01477                 goto notfound;
01478             }
01479             if (!(hMem = LoadResource( hInstance, hRsrc )))
01480             {
01481                 goto notfound;
01482             }
01483 
01484             pBits = (LPBYTE)LockResource( hMem );
01485 
01486             if(nFlags & LR_DEFAULTSIZE)
01487             {
01488                 iTargetCY = GetSystemMetrics(SM_CYICON);
01489                 iTargetCX = GetSystemMetrics(SM_CXICON);
01490             }
01491 
01492             /* Create a New Icon with the proper dimension
01493             */
01494             hNew = CURSORICON_CreateFromResource( hInstance, dwResGroupId, 0, pBits, dwBytesInRes,
01495                                                   bIsIcon, 0x00030000, iTargetCX, iTargetCY, nFlags);
01496             FreeResource(hMem);
01497         }
01498     }
01499     else
01500     {
01501             hNew = CURSORICON_Copy(Handle);
01502     }
01503     return hNew;
01504 
01505 notfound:
01506     dprintf(("WARNING: unable to find resource associated with icon/cursor -> copy without scaling!"));
01507     hNew = CURSORICON_Copy(Handle);
01508     return hNew;
01509 }
01510 
01511 /**********************************************************************
01512  *          CURSORICON_FindBestIcon
01513  *
01514  * Find the icon closest to the requested size and number of colors.
01515  */
01516 static CURSORICONDIRENTRY *CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width,
01517                                                     int height, int colors )
01518 {
01519     int i;
01520     CURSORICONDIRENTRY *entry, *bestEntry = NULL;
01521     UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
01522     UINT iTempXDiff, iTempYDiff, iTempColorDiff;
01523 
01524     if (dir->idCount < 1)
01525     {
01526         dprintf(("Empty directory!\n" ));
01527         return NULL;
01528     }
01529     if (dir->idCount == 1) return &dir->idEntries[0];  /* No choice... */
01530 
01531     /* Find Best Fit */
01532     iTotalDiff = 0xFFFFFFFF;
01533     iColorDiff = 0xFFFFFFFF;
01534     for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
01535     {
01536         iTempXDiff = abs(width - entry->ResInfo.icon.bWidth);
01537         iTempYDiff = abs(height - entry->ResInfo.icon.bHeight);
01538 
01539         if(iTotalDiff > (iTempXDiff + iTempYDiff))
01540         {
01541             iXDiff = iTempXDiff;
01542             iYDiff = iTempYDiff;
01543             iTotalDiff = iXDiff + iYDiff;
01544         }
01545     }
01546 
01547     /* Find Best Colors for Best Fit */
01548     for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
01549     {
01550         if(abs(width - entry->ResInfo.icon.bWidth) == iXDiff &&
01551             abs(height - entry->ResInfo.icon.bHeight) == iYDiff)
01552         {
01553 #ifdef __WIN32OS2__
01554             iTempColorDiff = abs(colors - (1 << entry->wBitCount));
01555 #else
01556             iTempColorDiff = abs(colors - entry->ResInfo.icon.bColorCount);
01557 #endif
01558             if(iColorDiff > iTempColorDiff)
01559             {
01560                 bestEntry = entry;
01561                 iColorDiff = iTempColorDiff;
01562             }
01563         }
01564     }
01565 ////testestest
01566     dprintf(("CURSORICON_FindBestIcon (%d,%d) %d -> %d", width, height, colors, (bestEntry) ? bestEntry->wResId : 0));
01567     return bestEntry;
01568 }
01569 
01570 
01571 /**********************************************************************
01572  *          CURSORICON_FindBestCursor
01573  *
01574  * Find the cursor closest to the requested size.
01575  * FIXME: parameter 'color' ignored and entries with more than 1 bpp
01576  *        ignored too
01577  */
01578 static CURSORICONDIRENTRY *CURSORICON_FindBestCursor( CURSORICONDIR *dir,
01579                                                       int width, int height, int color)
01580 {
01581     int i, maxwidth, maxheight;
01582     CURSORICONDIRENTRY *entry, *bestEntry = NULL;
01583 
01584     if (dir->idCount < 1)
01585     {
01586         dprintf(("Empty directory!\n" ));
01587         return NULL;
01588     }
01589     if (dir->idCount == 1) return &dir->idEntries[0]; /* No choice... */
01590 
01591     /* Double height to account for AND and XOR masks */
01592 
01593     height *= 2;
01594 
01595     /* First find the largest one smaller than or equal to the requested size*/
01596 
01597     maxwidth = maxheight = 0;
01598     for(i = 0,entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
01599         if ((entry->ResInfo.cursor.wWidth <= width) && (entry->ResInfo.cursor.wHeight <= height) &&
01600             (entry->ResInfo.cursor.wWidth > maxwidth) && (entry->ResInfo.cursor.wHeight > maxheight) &&
01601             (entry->wBitCount == 1))
01602         {
01603             bestEntry = entry;
01604             maxwidth  = entry->ResInfo.cursor.wWidth;
01605             maxheight = entry->ResInfo.cursor.wHeight;
01606         }
01607     if (bestEntry) return bestEntry;
01608 
01609     /* Now find the smallest one larger than the requested size */
01610 
01611     maxwidth = maxheight = 255;
01612     for(i = 0,entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++)
01613         if ((entry->ResInfo.cursor.wWidth < maxwidth) && (entry->ResInfo.cursor.wHeight < maxheight) &&
01614             (entry->wBitCount == 1))
01615         {
01616             bestEntry = entry;
01617             maxwidth  = entry->ResInfo.cursor.wWidth;
01618             maxheight = entry->ResInfo.cursor.wHeight;
01619         }
01620 
01621     return bestEntry;
01622 }
01623 /**********************************************************************
01624  *          LookupIconIdFromDirectoryEx       (USER.364)
01625  *
01626  * FIXME: exact parameter sizes
01627  */
01628 INT WIN32API LookupIconIdFromDirectoryEx(LPBYTE xdir, BOOL bIcon,
01629                                          INT width, INT height, UINT cFlag )
01630 {
01631     CURSORICONDIR       *dir = (CURSORICONDIR*)xdir;
01632     UINT retVal = 0;
01633 
01634     dprintf(("LookupIconIdFromDirectoryEx %x %d (%d,%d)", xdir, bIcon, width, height));
01635     if( dir && !dir->idReserved && (dir->idType & 3) )
01636     {
01637         CURSORICONDIRENTRY* entry;
01638         HDC hdc;
01639         UINT palEnts;
01640         int colors;
01641         hdc = GetDC(0);
01642         palEnts = GetSystemPaletteEntries(hdc, 0, 0, NULL);
01643         if (palEnts == 0)
01644             palEnts = 256;
01645         colors = (cFlag & LR_MONOCHROME) ? 2 : palEnts;
01646 
01647         ReleaseDC(0, hdc);
01648 
01649         if( bIcon )
01650             entry = CURSORICON_FindBestIcon( dir, width, height, colors );
01651         else
01652             entry = CURSORICON_FindBestCursor( dir, width, height, 1);
01653 
01654         if( entry ) retVal = entry->wResId;
01655     }
01656     else dprintf(("invalid resource directory\n"));
01657     return retVal;
01658 }
01659 /**********************************************************************
01660  *          LookupIconIdFromDirectory           (USER32.379)
01661  */
01662 INT WIN32API LookupIconIdFromDirectory( LPBYTE dir, BOOL bIcon )
01663 {
01664     return LookupIconIdFromDirectoryEx( dir, bIcon,
01665            bIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR),
01666            bIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR), bIcon ? 0 : LR_MONOCHROME );
01667 }
01668 //******************************************************************************
01669 //******************************************************************************
01670 
01671 //ICON cache implementation (Wine code)
01672 
01673 /**********************************************************************
01674  *      CURSORICON_FindSharedIcon
01675  */
01676 static HANDLE CURSORICON_FindSharedIcon( HMODULE hModule, HRSRC hRsrc )
01677 {
01678     HANDLE handle = 0;
01679     ICONCACHE *ptr;
01680 
01681     EnterCriticalSection( &IconCrst );
01682 
01683     for ( ptr = IconAnchor; ptr; ptr = ptr->next )
01684         if ( ptr->hModule == hModule && ptr->hRsrc == hRsrc )
01685         {
01686             ptr->count++;
01687             handle = ptr->handle;
01688             break;
01689         }
01690 
01691     LeaveCriticalSection( &IconCrst );
01692 
01693     return handle;
01694 }
01695 
01696 /*************************************************************************
01697  * CURSORICON_FindCache
01698  *
01699  * Given a handle, find the corresponding cache element
01700  *
01701  * PARAMS
01702  *      Handle     [I] handle to an Image
01703  *
01704  * RETURNS
01705  *     Success: The cache entry
01706  *     Failure: NULL
01707  *
01708  */
01709 static ICONCACHE* CURSORICON_FindCache(HANDLE handle)
01710 {
01711     ICONCACHE *ptr;
01712     ICONCACHE *pRet=NULL;
01713     BOOL IsFound = FALSE;
01714     int count;
01715 
01716     EnterCriticalSection( &IconCrst );
01717 
01718     for (count = 0, ptr = IconAnchor; ptr != NULL && !IsFound; ptr = ptr->next, count++ )
01719     {
01720         if ( handle == ptr->handle )
01721         {
01722             IsFound = TRUE;
01723             pRet = ptr;
01724         }
01725     }
01726 
01727     LeaveCriticalSection( &IconCrst );
01728 
01729     return pRet;
01730 }
01731 
01732 /**********************************************************************
01733  *      CURSORICON_AddSharedIcon
01734  */
01735 static void CURSORICON_AddSharedIcon( HMODULE hModule, HRSRC hRsrc, HRSRC hGroupRsrc, HANDLE handle )
01736 {
01737     ICONCACHE *ptr = (ICONCACHE *)HeapAlloc( GetProcessHeap(), 0, sizeof(ICONCACHE) );
01738     if ( !ptr ) return;
01739 
01740     ptr->hModule = hModule;
01741     ptr->hRsrc   = hRsrc;
01742     ptr->handle  = handle;
01743     ptr->hGroupRsrc = hGroupRsrc;
01744     ptr->count   = 1;
01745 
01746     EnterCriticalSection( &IconCrst );
01747     ptr->next    = IconAnchor;
01748     IconAnchor   = ptr;
01749     LeaveCriticalSection( &IconCrst );
01750 }
01751 
01752 /**********************************************************************
01753  *      CURSORICON_DelSharedIcon
01754  */
01755 static INT CURSORICON_DelSharedIcon( HANDLE handle )
01756 {
01757     INT count = -1;
01758     ICONCACHE *ptr;
01759 
01760     EnterCriticalSection( &IconCrst );
01761 
01762     for ( ptr = IconAnchor; ptr; ptr = ptr->next )
01763         if ( ptr->handle == handle )
01764         {
01765             if ( ptr->count > 0 ) ptr->count--;
01766             count = ptr->count;
01767             break;
01768         }
01769 
01770     LeaveCriticalSection( &IconCrst );
01771 
01772     return count;
01773 }
01774 
01775 /**********************************************************************
01776  *      CURSORICON_FreeModuleIcons
01777  */
01778 void CURSORICON_FreeModuleIcons( HMODULE hModule )
01779 {
01780     ICONCACHE **ptr = &IconAnchor;
01781 
01782     EnterCriticalSection( &IconCrst );
01783 
01784     while ( *ptr )
01785     {
01786         if ( (*ptr)->hModule == hModule )
01787         {
01788             ICONCACHE *freePtr = *ptr;
01789             *ptr = freePtr->next;
01790 
01791 #ifdef __WIN32OS2__
01792             CURSORICON_Destroy(freePtr->handle, CID_NONSHARED);
01793 #else
01794             GlobalFree( freePtr->handle );
01795 #endif
01796             HeapFree( GetProcessHeap(), 0, freePtr );
01797             continue;
01798         }
01799         ptr = &(*ptr)->next;
01800     }
01801 
01802     LeaveCriticalSection( &IconCrst );
01803 }
01804 

Generated on Wed Jan 23 23:17:53 2002 for ODIN-user32 by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001