BOOL CreateTooltipBitmap(PTOOLTIPWND pttwnd, UINT cx, UINT cy) { HDC hdc; if (pttwnd->hdcMem == NULL) { RIPMSG0(RIP_WARNING, "CreateTooltipBitmap: pttwnd->hdcMem is NULL"); return FALSE; } DestroyTooltipBitmap(pttwnd); hdc = GetTooltipDC(pttwnd); pttwnd->hbmMem = GreCreateCompatibleBitmap(hdc, cx, cy); _ReleaseDC(hdc); if (pttwnd->hbmMem == NULL) { RIPMSG0(RIP_WARNING, "CreateTooltipBitmap: hbmMem is NULL"); return FALSE; } GreSelectBitmap(pttwnd->hdcMem, pttwnd->hbmMem); return TRUE; }
BOOL _InternalGetIconInfo( IN PCURSOR pcur, OUT PICONINFO piconinfo, OUT OPTIONAL PUNICODE_STRING pstrInstanceName, OUT OPTIONAL PUNICODE_STRING pstrResName, OUT OPTIONAL LPDWORD pbpp, IN BOOL fInternalCursor) { HBITMAP hbmBitsT; HBITMAP hbmDstT; HBITMAP hbmMask; HBITMAP hbmColor; /* * If this is an animated cursor, just grab the first frame and return * the info for it. */ if (pcur->CURSORF_flags & CURSORF_ACON) pcur = ((PACON)pcur)->aspcur[0]; /* * Make copies of the bitmaps * * If the color bitmap is around, then there is no XOR mask in the * hbmMask bitmap. */ hbmMask = GreCreateBitmap( pcur->cx, (pcur->hbmColor && !fInternalCursor) ? pcur->cy / 2 : pcur->cy, 1, 1, NULL); if (hbmMask == NULL) return FALSE; hbmColor = NULL; if (pcur->hbmColor != NULL) { hbmColor = GreCreateCompatibleBitmap(gpDispInfo->hdcBits, pcur->cx, pcur->cy / 2); if (hbmColor == NULL) { GreDeleteObject(hbmMask); return FALSE; } } hbmBitsT = GreSelectBitmap(ghdcMem2, pcur->hbmMask); hbmDstT = GreSelectBitmap(ghdcMem, hbmMask); GreBitBlt(ghdcMem, 0, 0, pcur->cx, (pcur->hbmColor && !fInternalCursor) ? pcur->cy / 2 : pcur->cy, ghdcMem2, 0, 0, SRCCOPY, 0x00ffffff); if (hbmColor != NULL) { GreSelectBitmap(ghdcMem2, pcur->hbmColor); GreSelectBitmap(ghdcMem, hbmColor); GreBitBlt(ghdcMem, 0, 0, pcur->cx, pcur->cy / 2, ghdcMem2, 0, 0, SRCCOPY, 0); } GreSelectBitmap(ghdcMem2, hbmBitsT); GreSelectBitmap(ghdcMem, hbmDstT); /* * Fill in the iconinfo structure. make copies of the bitmaps. */ try { piconinfo->fIcon = (pcur->rt == LOWORD(RT_ICON)); piconinfo->xHotspot = pcur->xHotspot; piconinfo->yHotspot = pcur->yHotspot; piconinfo->hbmMask = hbmMask; piconinfo->hbmColor = hbmColor; if (pstrInstanceName != NULL) { if (pcur->atomModName) { pstrInstanceName->Length = UserGetAtomName(pcur->atomModName, pstrInstanceName->Buffer, pstrInstanceName->MaximumLength / sizeof(WCHAR)) * sizeof(WCHAR); } else { pstrInstanceName->Length = 0; } } if (pstrResName != NULL) { if (HIWORD(pcur->strName.Buffer)) { RtlCopyUnicodeString(pstrResName, &pcur->strName); } else { *pstrResName = pcur->strName; } } if (pbpp) *pbpp = pcur->bpp; } except (EXCEPTION_EXECUTE_HANDLER) { GreDeleteObject(hbmMask); GreDeleteObject(hbmColor); return FALSE; } return TRUE; }
/***************************************************************************\ * DrawIconEx * * Draws icon in desired size. * \***************************************************************************/ BOOL _DrawIconEx( HDC hdc, int x, int y, PCURSOR pcur, int cx, int cy, UINT istepIfAniCur, HBRUSH hbr, UINT diFlags) { BOOL fSuccess = FALSE; /* * If this is an animated cursor, just grab the ith frame and use it * for drawing. */ if (pcur->CURSORF_flags & CURSORF_ACON) { if ((int)istepIfAniCur >= ((PACON)pcur)->cicur) { RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "DrawIconEx, icon step out of range."); goto Done; } pcur = ((PACON)pcur)->aspcur[((PACON)pcur)->aicur[istepIfAniCur]]; } /* * Setup defaults. */ cx = GetCWidth(cx, diFlags, pcur->cx); cy = GetCHeight(cy, diFlags, (pcur->cy / 2)); if (hbr) { HBITMAP hbmpT = NULL; HDC hdcT; HBITMAP hbmpOld; POLYPATBLT PolyData; if (hdcT = GreCreateCompatibleDC(hdc)) { if (hbmpT = GreCreateCompatibleBitmap(hdc, cx, cy)) { POINT pt; BOOL bRet; hbmpOld = GreSelectBitmap(hdcT, hbmpT); /* * Set new dc's brush origin in same relative * location as passed-in dc's. */ bRet = GreGetBrushOrg(hdc, &pt); /* * Bug 292396 - joejo * Stop overactive asserts by replacing with RIPMSG. */ if (bRet != TRUE) { RIPMSG0(RIP_WARNING, "DrawIconEx, GreGetBrushOrg failed."); } bRet = GreSetBrushOrg(hdcT, pt.x, pt.y, NULL); if (bRet != TRUE) { RIPMSG0(RIP_WARNING, "DrawIconEx, GreSetBrushOrg failed."); } PolyData.x = 0; PolyData.y = 0; PolyData.cx = cx; PolyData.cy = cy; PolyData.BrClr.hbr = hbr; bRet = GrePolyPatBlt(hdcT, PATCOPY, &PolyData, 1, PPB_BRUSH); if (bRet != TRUE) { RIPMSG0(RIP_WARNING, "DrawIconEx, GrePolyPatBlt failed."); } /* * Output the image to the temporary memoryDC. */ BltIcon(hdcT, 0, 0, cx, cy, ghdcMem, pcur, TRUE, SRCAND); BltIcon(hdcT, 0, 0, cx, cy, ghdcMem, pcur, FALSE, SRCINVERT); /* * Blt the bitmap to the original DC. */ GreBitBlt(hdc, x, y, cx, cy, hdcT, 0, 0, SRCCOPY, (COLORREF)-1); GreSelectBitmap(hdcT, hbmpOld); bRet = GreDeleteObject(hbmpT); if (bRet != TRUE) { RIPMSG0(RIP_WARNING, "DrawIconEx, GreDeleteObject failed. Possible Leak"); } fSuccess = TRUE; } GreDeleteDC(hdcT); } } else { if (diFlags & DI_MASK) { BltIcon(hdc, x, y, cx, cy, ghdcMem, pcur, TRUE, ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY)); } if (diFlags & DI_IMAGE) { BltIcon(hdc, x, y, cx, cy, ghdcMem, pcur, FALSE, ((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY)); } fSuccess = TRUE; } Done: return fSuccess; }
HBITMAP xxxExpandBitmap( HBITMAP hbm) { int nx; int ny; BITMAP bm; HBITMAP hbmNew; HBITMAP hbmD; LPRECT lprc; RECT rc; PMONITOR pMonitor; TL tlpMonitor; /* * Get the dimensions of the screen and bitmap we'll * be dealing with. We'll adjust the xScreen/yScreen * to reflect the new surface size. The default adjustment * is to stretch the image to fit the screen. */ GreExtGetObjectW(hbm, sizeof(bm), (PBITMAP)&bm); pMonitor = GetPrimaryMonitor(); lprc = &pMonitor->rcMonitor; nx = (lprc->right / TILE_XMINSIZE) / bm.bmWidth; ny = (lprc->bottom / TILE_YMINSIZE) / bm.bmHeight; if (nx == 0) nx++; if (ny == 0) ny++; if ((nx + ny) <= 2) return hbm; /* * Create the surface for the new-bitmap. */ rc.left = rc.top = 0; rc.right = nx * bm.bmWidth; rc.bottom = ny * bm.bmHeight; hbmD = GreSelectBitmap(ghdcMem, hbm); hbmNew = GreCreateCompatibleBitmap(ghdcMem, rc.right, rc.bottom); GreSelectBitmap(ghdcMem, hbmD); if (hbmNew == NULL) return hbm; if (hbmD = GreSelectBitmap(ghdcMem2, hbmNew)) { /* * Expand the bitmap to the new surface. */ ThreadLockAlways(pMonitor, &tlpMonitor); xxxDrawWallpaper(NULL, ghdcMem2, pMonitor, &rc); ThreadUnlock(&tlpMonitor); GreSelectBitmap(ghdcMem2, hbmD); } GreDeleteObject(hbm); GreSetBitmapOwner(hbmNew, OBJECT_OWNER_PUBLIC); return hbmNew; }
HBITMAP ConvertToDDB( HDC hdc, HBITMAP hbmOld, HPALETTE hpal) { BITMAP bm; HBITMAP hbmNew; /* * This object must be a REALDIB type bitmap. */ GreExtGetObjectW(hbmOld, sizeof(bm), &bm); /* * Create the new wallpaper-surface. */ if (hbmNew = GreCreateCompatibleBitmap(hdc, bm.bmWidth, bm.bmHeight)) { HPALETTE hpalDst; HPALETTE hpalSrc; HBITMAP hbmDst; HBITMAP hbmSrc; UINT bpp; BOOL fHalftone = FALSE; /* * Select in the surfaces. */ hbmDst = GreSelectBitmap(ghdcMem2, hbmNew); hbmSrc = GreSelectBitmap(ghdcMem, hbmOld); /* * Determine image bits/pixel. */ bpp = (bm.bmPlanes * bm.bmBitsPixel); /* * Use the palette if given. If the image is of a greater * resolution than the device, then we're going to go through * a halftone-palette to get better colors. */ if (hpal) { hpalDst = _SelectPalette(ghdcMem2, hpal, FALSE); hpalSrc = _SelectPalette(ghdcMem, hpal, FALSE); xxxRealizePalette(ghdcMem2); /* * Set the halftoning for the destination. This is done * for images of greater resolution than the device. */ if (bpp > gpsi->BitCount) { fHalftone = TRUE; DoHTColorAdjust(ghdcMem2); } } /* * Set the stretchbltmode. This is more necessary when doing * halftoning. Since otherwise, the colors won't translate * correctly. */ SetBestStretchMode(ghdcMem2, bpp, fHalftone); /* * Set the new surface bits. Use StretchBlt() so the SBMode * will be used in color-translation. */ GreStretchBlt(ghdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, ghdcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY, 0); /* * Restore palettes. */ if (hpal) { _SelectPalette(ghdcMem2, hpalDst, FALSE); _SelectPalette(ghdcMem, hpalSrc, FALSE); } /* * Restore the surfaces. */ GreSelectBitmap(ghdcMem2, hbmDst); GreSelectBitmap(ghdcMem, hbmSrc); GreDeleteObject(hbmOld); GreSetBitmapOwner(hbmNew, OBJECT_OWNER_PUBLIC); } else { hbmNew = hbmOld; } return hbmNew; }
BOOL xxxSnapWindow( PWND pwnd) { PTHREADINFO ptiCurrent; RECT rc; HDC hdcScr = NULL; HDC hdcMem = NULL; BOOL fRet; HBITMAP hbmOld; HBITMAP hbm; HANDLE hPal; LPLOGPALETTE lppal; int palsize; int iFixedPaletteEntries; BOOL fSuccess; PWND pwndT; TL tlpwndT; PWINDOWSTATION pwinsta; TL tlpwinsta; CheckLock(pwnd); UserAssert(pwnd); ptiCurrent = PtiCurrent(); /* * If this is a thread of winlogon, don't do the snapshot. */ if (GetCurrentProcessId() == gpidLogon) return FALSE; /* * Get the affected windowstation */ if (!NT_SUCCESS(ReferenceWindowStation( PsGetCurrentThread(), NULL, WINSTA_READSCREEN, &pwinsta, TRUE)) || pwinsta->dwWSF_Flags & WSF_NOIO) { return FALSE; } /* * If the window is on another windowstation, do nothing */ if (pwnd->head.rpdesk->rpwinstaParent != pwinsta) return FALSE; /* * Get the parent of any child windows. */ while ((pwnd != NULL) && TestWF(pwnd, WFCHILD)) { pwnd = pwnd->spwndParent; } /* * Lock the windowstation before we leave the critical section */ ThreadLockWinSta(ptiCurrent, pwinsta, &tlpwinsta); /* * Open the clipboard and empty it. * * pwndDesktop is made the owner of the clipboard, instead of the * currently active window; -- SANKAR -- 20th July, 1989 -- */ pwndT = ptiCurrent->rpdesk->pDeskInfo->spwnd; ThreadLockWithPti(ptiCurrent, pwndT, &tlpwndT); fSuccess = xxxOpenClipboard(pwndT, NULL); ThreadUnlock(&tlpwndT); if (!fSuccess) { ThreadUnlockWinSta(ptiCurrent, &tlpwinsta); return FALSE; } xxxEmptyClipboard(pwinsta); /* * Use the whole window. */ CopyRect(&rc, &pwnd->rcWindow); /* * Only snap what is on the screen. */ if (!IntersectRect(&rc, &rc, &gpDispInfo->rcScreen)) { fRet = FALSE; goto SnapExit; } rc.right -= rc.left; rc.bottom -= rc.top; /* * Figure out how far offset from window origin visible part is */ if (pwnd != PWNDDESKTOP(pwnd)) { rc.left -= pwnd->rcWindow.left; rc.top -= pwnd->rcWindow.top; } /* * Get the entire window's DC. */ hdcScr = _GetWindowDC(pwnd); if (!hdcScr) goto MemoryError; /* * Create the memory DC. */ hdcMem = GreCreateCompatibleDC(hdcScr); if (!hdcMem) goto MemoryError; /* * Create the destination bitmap. If it fails, then attempt * to create a monochrome bitmap. * Did we have enough memory? */ if (SYSMET(SAMEDISPLAYFORMAT)) { hbm = GreCreateCompatibleBitmap(hdcScr, rc.right, rc.bottom); } else { hbm = GreCreateBitmap(rc.right, rc.bottom, 1, gpDispInfo->BitCountMax, NULL); } if (!hbm) { hbm = GreCreateBitmap(rc.right, rc.bottom, 1, 1, NULL); if (!hbm) goto MemoryError; } /* * Select the bitmap into the memory DC. */ hbmOld = GreSelectBitmap(hdcMem, hbm); /* * Snap!!! * Check the return value because the process taking the snapshot * may not have access to read the screen. */ fRet = GreBitBlt(hdcMem, 0, 0, rc.right, rc.bottom, hdcScr, rc.left, rc.top, SRCCOPY | CAPTUREBLT, 0); /* * Restore the old bitmap into the memory DC. */ GreSelectBitmap(hdcMem, hbmOld); /* * If the blt failed, leave now. */ if (!fRet) goto SnapExit; _SetClipboardData(CF_BITMAP, hbm, FALSE, TRUE); /* * If this is a palette device, let's throw the current system palette * into the clipboard also. Useful if the user just snapped a window * containing palette colors... */ if (TEST_PUSIF(PUSIF_PALETTEDISPLAY)) { int i; int iPalSize; palsize = GreGetDeviceCaps(hdcScr, SIZEPALETTE); /* * Determine the number of system colors. */ if (GreGetSystemPaletteUse(hdcScr) == SYSPAL_STATIC) iFixedPaletteEntries = GreGetDeviceCaps(hdcScr, NUMRESERVED); else iFixedPaletteEntries = 2; lppal = (LPLOGPALETTE)UserAllocPoolWithQuota( (LONG)(sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * palsize), TAG_CLIPBOARD); if (lppal != NULL) { lppal->palVersion = 0x300; lppal->palNumEntries = (WORD)palsize; if (GreGetSystemPaletteEntries(hdcScr, 0, palsize, lppal->palPalEntry)) { iPalSize = palsize - iFixedPaletteEntries / 2; for (i = iFixedPaletteEntries / 2; i < iPalSize; i++) { /* * Any non system palette enteries need to have the NOCOLLAPSE * flag set otherwise bitmaps containing different palette * indices but same colors get messed up. */ lppal->palPalEntry[i].peFlags = PC_NOCOLLAPSE; } if (hPal = GreCreatePalette(lppal)) _SetClipboardData(CF_PALETTE, hPal, FALSE, TRUE); } UserFreePool(lppal); } } PlayEventSound(USER_SOUND_SNAPSHOT); fRet = TRUE; SnapExit: /* * Release the window/client DC. */ if (hdcScr) { _ReleaseDC(hdcScr); } xxxCloseClipboard(pwinsta); Unlock(&pwinsta->spwndClipOwner); /* * Delete the memory DC. */ if (hdcMem) { GreDeleteDC(hdcMem); } ThreadUnlockWinSta(ptiCurrent, &tlpwinsta); return fRet; MemoryError: /* * Display an error message box. */ ClientNoMemoryPopup(); fRet = FALSE; goto SnapExit; }