Changeset 5385 for trunk/src/user32/winicon.cpp
- Timestamp:
- Mar 27, 2001, 6:17:52 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/user32/winicon.cpp
r4825 r5385 1 /* $Id: winicon.cpp,v 1. 19 2000-12-17 15:04:14sandervl Exp $ */1 /* $Id: winicon.cpp,v 1.20 2001-03-27 16:17:52 sandervl Exp $ */ 2 2 /* 3 3 * Win32 Icon Code for OS/2 … … 14 14 * 1998 Turchanov Sergey 15 15 * 1998 Huw D M Davies 16 * Theory: 17 * 18 * http://www.microsoft.com/win32dev/ui/icons.htm 19 * 20 * Cursors and icons are stored in a global heap block, with the 21 * following layout: 22 * 23 * CURSORICONINFO info; 24 * BYTE[] ANDbits; 25 * BYTE[] XORbits; 26 * 27 * The bits structures are in the format of a device-dependent bitmap. 28 * 29 * This layout is very sub-optimal, as the bitmap bits are stored in 30 * the X client instead of in the server like other bitmaps; however, 31 * some programs (notably Paint Brush) expect to be able to manipulate 32 * the bits directly :-( 33 * 34 * FIXME: what are we going to do with animation and color (bpp > 1) cursors ?! 35 * 36 ************************************************************************************************** 37 * 38 * TODO: Scaling of system cursors (store them as resources in user32 instead of using PM pointers) 39 * TODO: We use the hColorBmp member of the CURSORICONINFO structure to store the PM cursor handle 40 * Might mess up PaintBrush (see above) 16 41 * 17 42 * Project Odin Software License can be found in LICENSE.TXT … … 27 52 #include <win\virtual.h> 28 53 #include "initterm.h" 54 #include "oslibres.h" 55 #include "oslibwin.h" 29 56 30 57 #define DBG_LOCALLOG DBG_winicon 31 58 #include "dbglocal.h" 32 59 33 static WORD ICON_HOTSPOT = 0x4242; 60 61 /********************************************************************** 62 * ICONCACHE for cursors/icons loaded with LR_SHARED. 63 * 64 * FIXME: This should not be allocated on the system heap, but on a 65 * subsystem-global heap (i.e. one for all Win16 processes, 66 * and one for each Win32 process). 67 */ 68 typedef struct tagICONCACHE 69 { 70 struct tagICONCACHE *next; 71 72 HMODULE hModule; 73 HRSRC hRsrc; 74 HRSRC hGroupRsrc; 75 HANDLE handle; 76 INT count; 77 } ICONCACHE; 78 79 static ICONCACHE *IconAnchor = NULL; 80 static CRITICAL_SECTION IconCrst = CRITICAL_SECTION_INIT; 81 static WORD ICON_HOTSPOT = 0x4242; 82 static HCURSOR hActiveCursor = 0; 83 34 84 35 85 static HGLOBAL CURSORICON_CreateFromResource( HINSTANCE hInstance, DWORD dwResGroupId, HGLOBAL hObj, LPBYTE bits, … … 43 93 CURSORICONDIR **res, LPBYTE **ptr); 44 94 95 static INT CURSORICON_DelSharedIcon( HANDLE handle ); 96 static void CURSORICON_AddSharedIcon( HMODULE hModule, HRSRC hRsrc, HRSRC hGroupRsrc, HANDLE handle ); 97 static HANDLE CURSORICON_FindSharedIcon( HMODULE hModule, HRSRC hRsrc ); 98 static ICONCACHE* CURSORICON_FindCache(HANDLE handle); 99 45 100 /*********************************************************************** 46 101 * CreateIcon (USER32.75) … … 63 118 info.hInstance = hInstance; 64 119 info.dwResGroupId = -1; 120 info.hColorBmp = 0; 65 121 return CreateCursorIconIndirect(0, &info, lpANDbits, lpXORbits); 66 122 } … … 126 182 info->hInstance = -1; 127 183 info->dwResGroupId = -1; 184 info->hColorBmp = 0; 185 128 186 /* Transfer the bitmap bits to the CURSORICONINFO structure */ 129 187 GetBitmapBits( iconinfo->hbmMask ,sizeAnd,(char*)(info + 1) ); … … 213 271 memcpy(&pInfo->bmiColors[0], (char *)(ciconinfo + 1) + coloroff, colorsize); 214 272 } 215 //else TODO: color masks (cur erntly unused in CreateDIBitmap)273 //else TODO: color masks (currently unused in CreateDIBitmap) 216 274 217 275 iconinfo->hbmColor = CreateDIBitmap(hdc, &pInfo->bmiHeader, CBM_INIT, src, pInfo, DIB_RGB_COLORS); … … 235 293 return TRUE; 236 294 } 295 //****************************************************************************** 296 //****************************************************************************** 297 HCURSOR WIN32API CreateCursor(HINSTANCE hInst, int xHotSpot, int yHotSpot, int nWidth, int nHeight, 298 const VOID *lpANDbits, const VOID *lpXORbits) 299 { 300 CURSORICONINFO info; 301 302 dprintf(("CreateCursor %dx%d spot=%d,%d xor=%p and=%p\n", 303 nWidth, nHeight, xHotSpot, yHotSpot, lpXORbits, lpANDbits)); 304 305 info.ptHotSpot.x = xHotSpot; 306 info.ptHotSpot.y = yHotSpot; 307 info.nWidth = nWidth; 308 info.nHeight = nHeight; 309 info.nWidthBytes = 0; 310 info.bPlanes = 1; 311 info.bBitsPerPixel = 1; 312 info.hInstance = hInst; 313 info.dwResGroupId = -1; 314 info.hColorBmp = 0; 315 316 return CreateCursorIconIndirect( 0, &info, lpANDbits, lpXORbits ); 317 } 318 //****************************************************************************** 319 //****************************************************************************** 320 BOOL WIN32API DestroyCursor( HCURSOR hCursor) 321 { 322 dprintf(("USER32: DestroyCursor %x", hCursor)); 323 return CURSORICON_Destroy( hCursor, CID_WIN32 ); 324 } 325 //****************************************************************************** 326 //****************************************************************************** 327 HCURSOR WIN32API GetCursor(void) 328 { 329 dprintf2(("USER32: GetCursor")); 330 return hActiveCursor; 331 } 332 //****************************************************************************** 333 //****************************************************************************** 334 HCURSOR WIN32API SetCursor( HCURSOR hCursor) 335 { 336 HCURSOR hOldCursor; 337 338 dprintf(("USER32: SetCursor %x (prev %x)", hCursor, hActiveCursor)); 339 if (hCursor == hActiveCursor) return hActiveCursor; /* No change */ 340 341 hOldCursor = hActiveCursor; 342 hActiveCursor = hCursor; 343 344 CURSORICONINFO *iconinfo = (CURSORICONINFO *)GlobalLock((HGLOBAL)hCursor); 345 if (!iconinfo) { 346 dprintf(("ERROR: Invalid cursor!")); 347 return 0; 348 } 349 if(!iconinfo->hColorBmp) { 350 dprintf(("SetCursor: invalid os/2 pointer handle!!")); 351 } 352 353 if(OSLibWinSetPointer(iconinfo->hColorBmp) == FALSE) { 354 dprintf(("OSLibWinSetPointer %x returned FALSE!!", iconinfo->hColorBmp)); 355 } 356 GlobalUnlock(hCursor); 357 358 return hOldCursor; 359 } 360 //****************************************************************************** 361 //****************************************************************************** 362 BOOL WIN32API GetCursorPos( PPOINT lpPoint) 363 { 364 dprintf2(("USER32: GetCursorPos %x", lpPoint)); 365 366 if (!lpPoint) return FALSE; 367 368 if (OSLibWinQueryPointerPos(lpPoint)) //POINT == POINTL 369 { 370 mapScreenPoint((OSLIBPOINT*)lpPoint); 371 return TRUE; 372 } 373 else return FALSE; 374 } 375 //****************************************************************************** 376 //****************************************************************************** 377 BOOL WIN32API SetCursorPos( int X, int Y) 378 { 379 dprintf(("USER32: SetCursorPos %d %d", X,Y)); 380 return OSLibWinSetPointerPos(X, mapScreenY(Y)); 381 } 382 //****************************************************************************** 383 //****************************************************************************** 384 /***************************************************************************** 385 * Name : BOOL WIN32API SetSystemCursor 386 * Purpose : The SetSystemCursor function replaces the contents of the system 387 * cursor specified by dwCursorId with the contents of the cursor 388 * specified by hCursor, and then destroys hCursor. This function 389 * lets an application customize the system cursors. 390 * Parameters: HCURSOR hCursor set specified system cursor to this cursor's 391 * contents, then destroy this 392 * DWORD dwCursorID system cursor specified by its identifier 393 * Variables : 394 * Result : If the function succeeds, the return value is TRUE. 395 * If the function fails, the return value is FALSE. To get extended 396 * error information, call GetLastError. 397 * Remark : 398 * Status : UNTESTED STUB 399 * 400 * Author : Patrick Haller [Thu, 1998/02/26 11:55] 401 *****************************************************************************/ 402 BOOL WIN32API SetSystemCursor(HCURSOR hCursor, DWORD dwCursorId) 403 { 404 dprintf(("USER32:SetSystemCursor (%08xh,%08x) not supported.\n", 405 hCursor, 406 dwCursorId)); 407 408 return DestroyCursor(hCursor); 409 } 410 //****************************************************************************** 411 //****************************************************************************** 412 int WIN32API ShowCursor( BOOL bShow) 413 { 414 dprintf2(("USER32: ShowCursor %d", bShow)); 415 return O32_ShowCursor(bShow); 416 } 417 //****************************************************************************** 418 //****************************************************************************** 237 419 /*********************************************************************** 238 * CreateCursorIconIndirect (USER.408)420 * CreateCursorIconIndirect 239 421 */ 240 422 HGLOBAL WIN32API CreateCursorIconIndirect( HINSTANCE hInstance, … … 276 458 LPBYTE bits; 277 459 460 #ifdef __WIN32OS2__ 461 //TODO: Can system cursors be loaded by name??? (#xxx) 462 if (fCursor && hInstance == NULL && !HIWORD(name)) 463 { 464 HCURSOR hCursor = OSLibWinQuerySysPointer((ULONG)name, width, height); 465 if(hCursor) 466 { 467 /* If shared icon, check whether it was already loaded */ 468 if ((loadflags & LR_SHARED) 469 && (h = CURSORICON_FindSharedIcon( -1, hCursor ) ) != 0 ) 470 { 471 dprintf(("Found icon/cursor in cache; returned old handle %x", h)); 472 return h; 473 } 474 475 HANDLE hObj = GlobalAlloc( GMEM_MOVEABLE, sizeof(CURSORICONINFO)); 476 if (!hObj) 477 { 478 DebugInt3(); 479 return 0; 480 } 481 CURSORICONINFO *info; 482 483 info = (CURSORICONINFO *)GlobalLock( hObj ); 484 info->ptHotSpot.x = 0; 485 info->ptHotSpot.y = 0; 486 info->nWidth = width; 487 info->nHeight = height; 488 info->nWidthBytes = width*height/8; 489 info->bPlanes = 1; 490 info->bBitsPerPixel = 1; 491 info->hColorBmp = hCursor; 492 info->hInstance = -1; 493 info->dwResGroupId = -1; 494 495 if (loadflags & LR_SHARED ) 496 CURSORICON_AddSharedIcon( -1, hCursor, -1, hObj ); 497 498 GlobalUnlock( hObj ); 499 500 return hObj; 501 } 502 } 503 #endif 278 504 if ( loadflags & LR_LOADFROMFILE ) /* Load from file */ 279 505 { 280 506 LPBYTE *ptr; 507 281 508 if (!CURSORICON_SimulateLoadingFromResourceW((LPWSTR)name, fCursor, &dir, &ptr)) 282 509 return 0; … … 288 515 h = CURSORICON_CreateFromResource( 0, -1, 0, bits, dirEntry->dwBytesInRes, 289 516 !fCursor, 0x00030000, width, height, loadflags); 517 290 518 HeapFree( GetProcessHeap(), 0, dir ); 291 519 HeapFree( GetProcessHeap(), 0, ptr ); … … 339 567 } 340 568 569 /* If shared icon, check whether it was already loaded */ 570 if ((loadflags & LR_SHARED) 571 && (h = CURSORICON_FindSharedIcon( hInstance, hRsrc ) ) != 0 ) 572 { 573 dprintf(("Found icon/cursor in cache; returned old handle %x", h)); 574 return h; 575 } 576 341 577 if (!(handle = LoadResource( hInstance, hRsrc ))) return 0; 342 578 bits = (LPBYTE)LockResource( handle ); … … 344 580 !fCursor, 0x00030000, width, height, loadflags); 345 581 FreeResource( handle ); 582 583 /* If shared icon, add to icon cache */ 584 585 if ( h && (loadflags & LR_SHARED) ) 586 CURSORICON_AddSharedIcon( hInstance, hRsrc, hGroupRsrc, h ); 346 587 347 588 } … … 706 947 if( !hXorBits || !hAndBits ) 707 948 { 708 dprintf(("\tunable to create an icon bitmap. \n"));949 dprintf(("\tunable to create an icon bitmap.")); 709 950 return 0; 710 951 } … … 739 980 info->bPlanes = bmpXor.bmPlanes; 740 981 info->bBitsPerPixel = bmpXor.bmBitsPixel; 741 info->hColorBmp = hXorBits;742 982 info->hInstance = hInstance; 743 983 info->dwResGroupId = dwResGroupId; 984 info->hColorBmp = 0; 744 985 745 986 /* Transfer the bitmap bits to the CURSORICONINFO structure */ … … 769 1010 GetBitmapBits( hXorBits, sizeXor, (char *)(info + 1) + sizeAnd); 770 1011 } 1012 if(!bIcon) { 1013 info->hColorBmp = OSLibWinCreateCursor(info, (char *)(info + 1), (LPBITMAP_W)&bmpAnd, (char *)(info + 1) + sizeAnd, (LPBITMAP_W)&bmpXor); 1014 dprintf(("Create cursor %x with OS/2 pointer handle %x", hObj, info->hColorBmp)); 1015 } 771 1016 GlobalUnlock( hObj ); 772 1017 } … … 789 1034 WORD retv; 790 1035 791 #if 0792 1036 /* Check whether destroying active cursor */ 793 1037 794 1038 if ( hActiveCursor == handle ) 795 1039 { 796 ERR_(cursor)("Destroying active cursor!\n");1040 dprintf(("WARNING: Destroying active cursor!" )); 797 1041 SetCursor( 0 ); 798 1042 } 1043 799 1044 /* Try shared cursor/icon first */ 800 801 1045 if ( !(flags & CID_NONSHARED) ) 802 1046 { … … 808 1052 /* FIXME: OEM cursors/icons should be recognized */ 809 1053 } 1054 /* Now assume non-shared cursor/icon */ 1055 1056 #ifdef __WIN32OS2__ 1057 CURSORICONINFO *iconinfo = (CURSORICONINFO *)GlobalLock((HGLOBAL)handle); 1058 if (!iconinfo) { 1059 dprintf(("ERROR: Invalid cursor!")); 1060 return 0; 1061 } 1062 1063 if(iconinfo->hColorBmp) { 1064 OSLibWinDestroyPointer(iconinfo->hColorBmp); 1065 } 1066 GlobalUnlock(handle); 810 1067 #endif 811 /* Now assume non-shared cursor/icon */812 1068 813 1069 retv = GlobalFree( handle ); … … 874 1130 || nFlags & LR_MONOCHROME) 875 1131 { 1132 ICONCACHE* pIconCache = CURSORICON_FindCache(Handle); 1133 1134 /* Not Found in Cache, then do a straight copy 1135 */ 1136 if(pIconCache == NULL) 1137 { 1138 #ifdef __WIN32OS2__ 1139 hNew = CURSORICON_Copy(Handle); 1140 #else 1141 hNew = CURSORICON_Copy(0, Handle); 1142 #endif 1143 if(nFlags & LR_COPYFROMRESOURCE) 1144 { 1145 dprintf(("WARNING: LR_COPYFROMRESOURCE: Failed to load from cache\n")); 1146 } 1147 } 1148 else 1149 { 876 1150 int iTargetCY = iDesiredCY, iTargetCX = iDesiredCX; 877 1151 LPBYTE pBits; … … 968 1242 bIsIcon, 0x00030000, iTargetCX, iTargetCY, nFlags); 969 1243 FreeResource(hMem); 1244 } 970 1245 } 971 1246 else … … 1005 1280 iColorDiff = 0xFFFFFFFF; 1006 1281 for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++) 1007 1282 { 1008 1283 iTempXDiff = abs(width - entry->ResInfo.icon.bWidth); 1009 1284 iTempYDiff = abs(height - entry->ResInfo.icon.bHeight); … … 1015 1290 iTotalDiff = iXDiff + iYDiff; 1016 1291 } 1017 1292 } 1018 1293 1019 1294 /* Find Best Colors for Best Fit */ 1020 1295 for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++) 1021 1296 { 1022 1297 if(abs(width - entry->ResInfo.icon.bWidth) == iXDiff && 1023 1298 abs(height - entry->ResInfo.icon.bHeight) == iYDiff) … … 1029 1304 #endif 1030 1305 if(iColorDiff > iTempColorDiff) 1031 {1032 bestEntry = entry;1306 { 1307 bestEntry = entry; 1033 1308 iColorDiff = iTempColorDiff; 1034 }1309 } 1035 1310 } 1036 1311 } … … 1049 1324 */ 1050 1325 static CURSORICONDIRENTRY *CURSORICON_FindBestCursor( CURSORICONDIR *dir, 1051 int width, int height, int color)1326 int width, int height, int color) 1052 1327 { 1053 1328 int i, maxwidth, maxheight; … … 1140 1415 //****************************************************************************** 1141 1416 //****************************************************************************** 1417 1418 //ICON cache implementation (Wine code) 1419 1420 /********************************************************************** 1421 * CURSORICON_FindSharedIcon 1422 */ 1423 static HANDLE CURSORICON_FindSharedIcon( HMODULE hModule, HRSRC hRsrc ) 1424 { 1425 HANDLE handle = 0; 1426 ICONCACHE *ptr; 1427 1428 EnterCriticalSection( &IconCrst ); 1429 1430 for ( ptr = IconAnchor; ptr; ptr = ptr->next ) 1431 if ( ptr->hModule == hModule && ptr->hRsrc == hRsrc ) 1432 { 1433 ptr->count++; 1434 handle = ptr->handle; 1435 break; 1436 } 1437 1438 LeaveCriticalSection( &IconCrst ); 1439 1440 return handle; 1441 } 1442 1443 /************************************************************************* 1444 * CURSORICON_FindCache 1445 * 1446 * Given a handle, find the corresponding cache element 1447 * 1448 * PARAMS 1449 * Handle [I] handle to an Image 1450 * 1451 * RETURNS 1452 * Success: The cache entry 1453 * Failure: NULL 1454 * 1455 */ 1456 static ICONCACHE* CURSORICON_FindCache(HANDLE handle) 1457 { 1458 ICONCACHE *ptr; 1459 ICONCACHE *pRet=NULL; 1460 BOOL IsFound = FALSE; 1461 int count; 1462 1463 EnterCriticalSection( &IconCrst ); 1464 1465 for (count = 0, ptr = IconAnchor; ptr != NULL && !IsFound; ptr = ptr->next, count++ ) 1466 { 1467 if ( handle == ptr->handle ) 1468 { 1469 IsFound = TRUE; 1470 pRet = ptr; 1471 } 1472 } 1473 1474 LeaveCriticalSection( &IconCrst ); 1475 1476 return pRet; 1477 } 1478 1479 /********************************************************************** 1480 * CURSORICON_AddSharedIcon 1481 */ 1482 static void CURSORICON_AddSharedIcon( HMODULE hModule, HRSRC hRsrc, HRSRC hGroupRsrc, HANDLE handle ) 1483 { 1484 ICONCACHE *ptr = (ICONCACHE *)HeapAlloc( GetProcessHeap(), 0, sizeof(ICONCACHE) ); 1485 if ( !ptr ) return; 1486 1487 ptr->hModule = hModule; 1488 ptr->hRsrc = hRsrc; 1489 ptr->handle = handle; 1490 ptr->hGroupRsrc = hGroupRsrc; 1491 ptr->count = 1; 1492 1493 EnterCriticalSection( &IconCrst ); 1494 ptr->next = IconAnchor; 1495 IconAnchor = ptr; 1496 LeaveCriticalSection( &IconCrst ); 1497 } 1498 1499 /********************************************************************** 1500 * CURSORICON_DelSharedIcon 1501 */ 1502 static INT CURSORICON_DelSharedIcon( HANDLE handle ) 1503 { 1504 INT count = -1; 1505 ICONCACHE *ptr; 1506 1507 EnterCriticalSection( &IconCrst ); 1508 1509 for ( ptr = IconAnchor; ptr; ptr = ptr->next ) 1510 if ( ptr->handle == handle ) 1511 { 1512 if ( ptr->count > 0 ) ptr->count--; 1513 count = ptr->count; 1514 break; 1515 } 1516 1517 LeaveCriticalSection( &IconCrst ); 1518 1519 return count; 1520 } 1521 1522 /********************************************************************** 1523 * CURSORICON_FreeModuleIcons 1524 */ 1525 void CURSORICON_FreeModuleIcons( HMODULE hModule ) 1526 { 1527 ICONCACHE **ptr = &IconAnchor; 1528 1529 EnterCriticalSection( &IconCrst ); 1530 1531 while ( *ptr ) 1532 { 1533 if ( (*ptr)->hModule == hModule ) 1534 { 1535 ICONCACHE *freePtr = *ptr; 1536 *ptr = freePtr->next; 1537 1538 #ifdef __WIN32OS2__ 1539 CURSORICON_Destroy(freePtr->handle, CID_NONSHARED); 1540 #else 1541 GlobalFree( freePtr->handle ); 1542 #endif 1543 HeapFree( GetProcessHeap(), 0, freePtr ); 1544 continue; 1545 } 1546 ptr = &(*ptr)->next; 1547 } 1548 1549 LeaveCriticalSection( &IconCrst ); 1550 } 1551
Note:
See TracChangeset
for help on using the changeset viewer.