/***************************************************************************\ * 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; }
/* * @implemented */ HBITMAP APIENTRY NtGdiSelectBitmap( IN HDC hdc, IN HBITMAP hbmp) { PDC pdc; PDC_ATTR pdcattr; HBITMAP hbmpOld; PSURFACE psurfNew; HRGN hVisRgn; SIZEL sizlBitmap = {1, 1}; HDC hdcOld; ASSERT_NOGDILOCKS(); /* Verify parameters */ if (hdc == NULL || hbmp == NULL) return NULL; /* First lock the DC */ pdc = DC_LockDc(hdc); if (!pdc) { return NULL; } pdcattr = pdc->pdcattr; /* Must be a memory dc to select a bitmap */ if (pdc->dctype != DC_TYPE_MEMORY) { DC_UnlockDc(pdc); return NULL; } /* Check if there was a bitmap selected before */ if (pdc->dclevel.pSurface) { /* Return its handle */ hbmpOld = pdc->dclevel.pSurface->BaseObject.hHmgr; } else { /* Return default bitmap */ hbmpOld = StockObjects[DEFAULT_BITMAP]; } /* Check if the default bitmap was passed */ if (hbmp == StockObjects[DEFAULT_BITMAP]) { psurfNew = NULL; // HACK psurfNew = SURFACE_ShareLockSurface(hbmp); } else { /* Reference the new bitmap and check if it's valid */ psurfNew = SURFACE_ShareLockSurface(hbmp); if (!psurfNew) { DC_UnlockDc(pdc); return NULL; } /* Set the bitmp's hdc */ hdcOld = InterlockedCompareExchangePointer((PVOID*)&psurfNew->hdc, hdc, 0); if (hdcOld != NULL && hdcOld != hdc) { /* The bitmap is already selected, fail */ SURFACE_ShareUnlockSurface(psurfNew); DC_UnlockDc(pdc); return NULL; } /* Get the bitmap size */ sizlBitmap = psurfNew->SurfObj.sizlBitmap; /* Check if the bitmap is a dibsection */ if(psurfNew->hSecure) { /* Set DIBSECTION attribute */ pdcattr->ulDirty_ |= DC_DIBSECTION; } else { pdcattr->ulDirty_ &= ~DC_DIBSECTION; } } /* Select the new surface, release the old */ DC_vSelectSurface(pdc, psurfNew); /* Set the new size */ pdc->dclevel.sizl = sizlBitmap; /* Release one reference we added */ SURFACE_ShareUnlockSurface(psurfNew); /* Mark the dc brushes invalid */ pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE; /* Unlock the DC */ DC_UnlockDc(pdc); /* FIXME; improve by using a region without a handle and selecting it */ hVisRgn = IntSysCreateRectRgn( 0, 0, sizlBitmap.cx, sizlBitmap.cy); if (hVisRgn) { GdiSelectVisRgn(hdc, hVisRgn); GreDeleteObject(hVisRgn); } /* Return the old bitmap handle */ return hbmpOld; }
/* Win32k counterpart of User DefWindowProc */ LRESULT FASTCALL IntDefWindowProc( PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL Ansi) { LRESULT lResult = 0; USER_REFERENCE_ENTRY Ref; if (Msg > WM_USER) return 0; switch (Msg) { case WM_SYSCOMMAND: { ERR("hwnd %p WM_SYSCOMMAND %lx %lx\n", Wnd->head.h, wParam, lParam ); lResult = DefWndHandleSysCommand(Wnd, wParam, lParam); break; } case WM_SHOWWINDOW: { if ((Wnd->style & WS_VISIBLE) && wParam) break; if (!(Wnd->style & WS_VISIBLE) && !wParam) break; if (!Wnd->spwndOwner) break; if (LOWORD(lParam)) { if (wParam) { if (!(Wnd->state & WNDS_HIDDENPOPUP)) break; Wnd->state &= ~WNDS_HIDDENPOPUP; } else Wnd->state |= WNDS_HIDDENPOPUP; co_WinPosShowWindow(Wnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE); } } break; case WM_CLIENTSHUTDOWN: return IntClientShutdown(Wnd, wParam, lParam); case WM_APPCOMMAND: ERR("WM_APPCOMMAND\n"); if ( (Wnd->style & (WS_POPUP|WS_CHILD)) != WS_CHILD && Wnd != co_GetDesktopWindow(Wnd) ) { if (!co_HOOK_CallHooks(WH_SHELL, HSHELL_APPCOMMAND, wParam, lParam)) co_IntShellHookNotify(HSHELL_APPCOMMAND, wParam, lParam); break; } UserRefObjectCo(Wnd->spwndParent, &Ref); lResult = co_IntSendMessage(UserHMGetHandle(Wnd->spwndParent), WM_APPCOMMAND, wParam, lParam); UserDerefObjectCo(Wnd->spwndParent); break; case WM_CTLCOLORMSGBOX: case WM_CTLCOLOREDIT: case WM_CTLCOLORLISTBOX: case WM_CTLCOLORBTN: case WM_CTLCOLORDLG: case WM_CTLCOLORSTATIC: case WM_CTLCOLORSCROLLBAR: return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX); case WM_CTLCOLOR: return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam)); case WM_GETHOTKEY: return DefWndGetHotKey(Wnd); case WM_SETHOTKEY: return DefWndSetHotKey(Wnd, wParam); case WM_NCHITTEST: { POINT Point; Point.x = GET_X_LPARAM(lParam); Point.y = GET_Y_LPARAM(lParam); return GetNCHitEx(Wnd, Point); } case WM_SYNCPAINT: { HRGN hRgn; Wnd->state &= ~WNDS_SYNCPAINTPENDING; ERR("WM_SYNCPAINT\n"); hRgn = IntSysCreateRectRgn(0, 0, 0, 0); if (co_UserGetUpdateRgn(Wnd, hRgn, FALSE) != NULLREGION) { if (!wParam) wParam = (RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN); co_UserRedrawWindow(Wnd, NULL, hRgn, wParam); } GreDeleteObject(hRgn); return 0; } case WM_SETREDRAW: if (wParam) { if (!(Wnd->style & WS_VISIBLE)) { IntSetStyle( Wnd, WS_VISIBLE, 0 ); Wnd->state |= WNDS_SENDNCPAINT; } } else { if (Wnd->style & WS_VISIBLE) { co_UserRedrawWindow( Wnd, NULL, NULL, RDW_ALLCHILDREN | RDW_VALIDATE ); IntSetStyle( Wnd, 0, WS_VISIBLE ); } } return 0; /* ReactOS only. */ case WM_CBT: { switch (wParam) { case HCBT_MOVESIZE: { RECTL rt; if (lParam) { _SEH2_TRY { ProbeForRead((PVOID)lParam, sizeof(RECT), 1); RtlCopyMemory(&rt, (PVOID)lParam, sizeof(RECT)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { lResult = 1; } _SEH2_END; } if (!lResult) lResult = co_HOOK_CallHooks(WH_CBT, HCBT_MOVESIZE, (WPARAM)Wnd->head.h, lParam ? (LPARAM)&rt : 0); } break; } break; } break; } return lResult; }
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; }
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; }
ULONG_PTR APIENTRY NtGdiPolyPolyDraw( IN HDC hDC, IN PPOINT UnsafePoints, IN PULONG UnsafeCounts, IN ULONG Count, IN INT iFunc ) { DC *dc; PVOID pTemp; LPPOINT SafePoints; PULONG SafeCounts; NTSTATUS Status = STATUS_SUCCESS; BOOL Ret = TRUE; ULONG nPoints = 0, nMaxPoints = 0, nInvalid = 0, i; if (!UnsafePoints || !UnsafeCounts || Count == 0 || iFunc == 0 || iFunc > GdiPolyPolyRgn) { /* Windows doesn't set last error */ return FALSE; } _SEH2_TRY { ProbeForRead(UnsafePoints, Count * sizeof(POINT), 1); ProbeForRead(UnsafeCounts, Count * sizeof(ULONG), 1); /* Count points and validate poligons */ for (i = 0; i < Count; i++) { if (UnsafeCounts[i] < 2) { nInvalid++; } nPoints += UnsafeCounts[i]; nMaxPoints = max(nMaxPoints, UnsafeCounts[i]); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END; if (!NT_SUCCESS(Status)) { /* Windows doesn't set last error */ return FALSE; } if (nPoints == 0 || nPoints < nMaxPoints) { /* If all polygon counts are zero, or we have overflow, return without setting a last error code. */ return FALSE; } if (nInvalid != 0) { /* If at least one poly count is 0 or 1, fail */ EngSetLastError(ERROR_INVALID_PARAMETER); return FALSE; } /* Allocate one buffer for both counts and points */ pTemp = ExAllocatePoolWithTag(PagedPool, Count * sizeof(ULONG) + nPoints * sizeof(POINT), TAG_SHAPE); if (!pTemp) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } SafeCounts = pTemp; SafePoints = (PVOID)(SafeCounts + Count); _SEH2_TRY { /* Pointers already probed! */ RtlCopyMemory(SafeCounts, UnsafeCounts, Count * sizeof(ULONG)); RtlCopyMemory(SafePoints, UnsafePoints, nPoints * sizeof(POINT)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END; if (!NT_SUCCESS(Status)) { ExFreePoolWithTag(pTemp, TAG_SHAPE); return FALSE; } /* Special handling for GdiPolyPolyRgn */ if (iFunc == GdiPolyPolyRgn) { PREGION Rgn; HRGN hRgn; Rgn = REGION_AllocUserRgnWithHandle(0); if (!Rgn) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); ExFreePoolWithTag(pTemp, TAG_SHAPE); return 0; } hRgn = Rgn->BaseObject.hHmgr; if (!IntSetPolyPolygonRgn(SafePoints, SafeCounts, Count, hDC ? 1 : 2, Rgn)) { /* EngSetLastError ? */ GreDeleteObject(hRgn); hRgn = NULL; } RGNOBJAPI_Unlock(Rgn); ExFreePoolWithTag(pTemp, TAG_SHAPE); return (ULONG_PTR)hRgn; } dc = DC_LockDc(hDC); if (!dc) { EngSetLastError(ERROR_INVALID_HANDLE); ExFreePoolWithTag(pTemp, TAG_SHAPE); return FALSE; } if (dc->dctype == DC_TYPE_INFO) { DC_UnlockDc(dc); ExFreePoolWithTag(pTemp, TAG_SHAPE); /* Yes, Windows really returns TRUE in this case */ return TRUE; } DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL); if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) DC_vUpdateFillBrush(dc); if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) DC_vUpdateLineBrush(dc); /* Perform the actual work */ switch (iFunc) { case GdiPolyPolygon: Ret = IntGdiPolyPolygon(dc, SafePoints, SafeCounts, Count); break; case GdiPolyPolyLine: Ret = IntGdiPolyPolyline(dc, SafePoints, SafeCounts, Count); break; case GdiPolyBezier: Ret = IntGdiPolyBezier(dc, SafePoints, *SafeCounts); break; case GdiPolyLineTo: Ret = IntGdiPolylineTo(dc, SafePoints, *SafeCounts); break; case GdiPolyBezierTo: Ret = IntGdiPolyBezierTo(dc, SafePoints, *SafeCounts); break; default: EngSetLastError(ERROR_INVALID_PARAMETER); Ret = FALSE; } /* Cleanup and return */ DC_vFinishBlit(dc, NULL); DC_UnlockDc(dc); ExFreePoolWithTag(pTemp, TAG_SHAPE); return (ULONG_PTR)Ret; }
BOOL xxxSetDeskWallpaper(PUNICODE_STRING pProfileUserName, LPWSTR lpszFile) { BITMAP bm; UINT WallpaperStyle2; PWND pwndShell; TL tl; PTHREADINFO ptiCurrent = PtiCurrent(); PDESKTOP pdesk; BOOL fRet = FALSE; HBITMAP hbmOld; PROFINTINFO apsi[] = { {PMAP_DESKTOP, (LPWSTR)STR_TILEWALL , 0, &gwWPStyle }, {PMAP_DESKTOP, (LPWSTR)STR_DTSTYLE , 0, &WallpaperStyle2 }, {PMAP_DESKTOP, (LPWSTR)STR_DTORIGINX, 0, &gsrcWallpaper.x }, {PMAP_DESKTOP, (LPWSTR)STR_DTORIGINY, 0, &gsrcWallpaper.y }, {0, NULL, 0, NULL } }; pdesk = ptiCurrent->rpdesk; hbmOld = ghbmWallpaper; /* * Get the shell-window. This could be NULL on system * initialization. We will use this to do palette realization. */ pwndShell = (pdesk ? pdesk->pDeskInfo->spwndShell : NULL); if ((lpszFile == SETWALLPAPER_METRICS) && !(gwWPStyle & DTF_STRETCH)) { gsrcWallpaper.x = 0; gsrcWallpaper.y = 0; if (ghbmWallpaper) goto CreateNewWallpaper; goto Metric_Change; } CreateNewWallpaper: /* * Delete the old wallpaper and palette if the exist. */ if (ghpalWallpaper) { GreDeleteObject(ghpalWallpaper); ghpalWallpaper = NULL; } if (ghbmWallpaper) { GreDeleteObject(ghbmWallpaper); ghbmWallpaper = NULL; } /* * Kill any SPBs no matter what. * Works if we're switching from/to palettized wallpaper. * Fixes a lot of problems because palette doesn't change, shell * paints funny on desktop, etc. */ FreeAllSpbs(); /* * If this is a metric-change (and stretched), then we need to * reload it. However, since we are called from the winlogon process * during a desktop-switch, we would be mapped to the wrong Luid * when we attempt to grab the name from GetDeskWallpaperName. This * would use the Luid from the DEFAULT user rather than the current * logged on user. In order to avoid this, we cache the wallpaer * name so that on METRIC-CHANGES we use the current-user's wallpaper. * * NOTE: we assume that prior to any METRIC change, we have already * setup the ghbmWallpaper and lpszCached. This is usually done * either on logon or during user desktop-changes through conrol-Panel. */ if (lpszFile == SETWALLPAPER_METRICS) { UserAssert(gpszWall != NULL); goto LoadWallpaper; } /* * Free the cached handle. */ if (gpszWall) { UserFreePool(gpszWall); gpszWall = NULL; } /* * Load the wallpaper-name. If this returns FALSE, then * the user specified (None). We will return true to force * the repainting of the desktop. */ gpszWall = GetDeskWallpaperName(pProfileUserName,lpszFile); if (!gpszWall) { fRet = TRUE; goto SDW_Exit; } /* * Retrieve the default settings from the registry. * * If tile is indicated, then normalize style to not include * FIT/STRETCH which are center-only styles. Likewise, if * we are centered, then normalize out the TILE bit. */ FastGetProfileIntsW(pProfileUserName, apsi); gwWPStyle &= DTF_TILE; if (!(gwWPStyle & DTF_TILE)) { gwWPStyle = WallpaperStyle2 & DTF_STRETCH; } /* * Load the wallpaper. This makes a callback to the client to * perform the bitmap-creation. */ LoadWallpaper: if (xxxLoadDesktopWallpaper(gpszWall) == FALSE) { gwWPStyle = 0; goto SDW_Exit; } /* * If we have a palette, then we need to do the correct realization and * notification. */ if (ghpalWallpaper != NULL) { PWND pwndSend; if (pwndShell) { pwndSend = pwndShell; } else { pwndSend = (pdesk ? pdesk->pDeskInfo->spwnd : NULL); } /* * Update the desktop with the new bitmap. This cleans * out the system-palette so colors can be realized. */ GreRealizeDefaultPalette(gpDispInfo->hdcScreen, TRUE); /* * Don't broadcast if system initialization is occuring. Otherwise * this gives the shell first-crack at realizing its colors * correctly. */ if (pwndSend) { HWND hwnd = HW(pwndSend); ThreadLockAlways(pwndSend, &tl); xxxSendNotifyMessage(pwndSend, WM_PALETTECHANGED, (WPARAM)hwnd, 0); ThreadUnlock(&tl); } } Metric_Change: if (fRet = GreExtGetObjectW(ghbmWallpaper, sizeof(bm), (PBITMAP)&bm)) { gsrcWallpaper.cx = bm.bmWidth; gsrcWallpaper.cy = bm.bmHeight; } // fall-through SDW_Exit: /* * Notify the shell-window that the wallpaper changed. */ if ((pwndShell != NULL) && ((hbmOld && !ghbmWallpaper) || (!hbmOld && ghbmWallpaper))) { ThreadLockAlways(pwndShell, &tl); xxxSendNotifyMessage(pwndShell, WM_SHELLNOTIFY, SHELLNOTIFY_WALLPAPERCHANGED, (LPARAM)ghbmWallpaper); ThreadUnlock(&tl); } return fRet; }
BOOL FASTCALL UITOOLS95_DrawFrameScroll(HDC dc, LPRECT r, UINT uFlags) { LOGFONTW lf; HFONT hFont, hOldFont; COLORREF clrsave; RECT myr; INT bkmode; WCHAR Symbol; switch(uFlags & 0xff) { case DFCS_SCROLLCOMBOBOX: case DFCS_SCROLLDOWN: Symbol = '6'; break; case DFCS_SCROLLUP: Symbol = '5'; break; case DFCS_SCROLLLEFT: Symbol = '3'; break; case DFCS_SCROLLRIGHT: Symbol = '4'; break; case DFCS_SCROLLSIZEGRIP: case DFCS_SCROLLSIZEGRIPRIGHT: RtlZeroMemory(&lf, sizeof(LOGFONTW)); UITOOLS_MakeSquareRect(r, &myr); lf.lfHeight = myr.bottom - myr.top; lf.lfWidth = 0; lf.lfWeight = FW_NORMAL; lf.lfCharSet = DEFAULT_CHARSET; RtlCopyMemory(lf.lfFaceName, L"Marlett", sizeof(L"Marlett")); hFont = GreCreateFontIndirectW(&lf); /* save font and text color */ hOldFont = NtGdiSelectFont(dc, hFont); clrsave = GreGetTextColor(dc); bkmode = GreGetBkMode(dc); /* set color and drawing mode */ IntGdiSetBkMode(dc, TRANSPARENT); if (!(uFlags & (DFCS_MONO | DFCS_FLAT))) { IntGdiSetTextColor(dc, IntGetSysColor(COLOR_BTNHIGHLIGHT)); /* draw selected symbol */ Symbol = ((uFlags & 0xff) == DFCS_SCROLLSIZEGRIP) ? 'o' : 'x'; GreTextOutW(dc, myr.left, myr.top, &Symbol, 1); IntGdiSetTextColor(dc, IntGetSysColor(COLOR_BTNSHADOW)); } else IntGdiSetTextColor(dc, IntGetSysColor(COLOR_WINDOWFRAME)); /* draw selected symbol */ Symbol = ((uFlags & 0xff) == DFCS_SCROLLSIZEGRIP) ? 'p' : 'y'; GreTextOutW(dc, myr.left, myr.top, &Symbol, 1); /* restore previous settings */ IntGdiSetTextColor(dc, clrsave); NtGdiSelectFont(dc, hOldFont); IntGdiSetBkMode(dc, bkmode); GreDeleteObject(hFont); return TRUE; default: return FALSE; } IntDrawRectEdge(dc, r, (uFlags & DFCS_PUSHED) ? EDGE_SUNKEN : EDGE_RAISED, (uFlags&DFCS_FLAT) | BF_MIDDLE | BF_RECT); RtlZeroMemory(&lf, sizeof(LOGFONTW)); UITOOLS_MakeSquareRect(r, &myr); myr.left += 1; myr.top += 1; myr.right -= 1; myr.bottom -= 1; if(uFlags & DFCS_PUSHED) RECTL_vOffsetRect(&myr,1,1); lf.lfHeight = myr.bottom - myr.top; lf.lfWidth = 0; lf.lfWeight = FW_NORMAL; lf.lfCharSet = DEFAULT_CHARSET; RtlCopyMemory(lf.lfFaceName, L"Marlett", sizeof(L"Marlett")); hFont = GreCreateFontIndirectW(&lf); /* save font and text color */ hOldFont = NtGdiSelectFont(dc, hFont); clrsave = GreGetTextColor(dc); bkmode = GreGetBkMode(dc); /* set color and drawing mode */ IntGdiSetBkMode(dc, TRANSPARENT); if(uFlags & DFCS_INACTIVE) { /* draw shadow */ IntGdiSetTextColor(dc, IntGetSysColor(COLOR_BTNHIGHLIGHT)); GreTextOutW(dc, myr.left + 1, myr.top + 1, &Symbol, 1); } IntGdiSetTextColor(dc, IntGetSysColor((uFlags & DFCS_INACTIVE) ? COLOR_BTNSHADOW : COLOR_BTNTEXT)); /* draw selected symbol */ GreTextOutW(dc, myr.left, myr.top, &Symbol, 1); /* restore previous settings */ IntGdiSetTextColor(dc, clrsave); NtGdiSelectFont(dc, hOldFont); IntGdiSetBkMode(dc, bkmode); GreDeleteObject(hFont); return TRUE; }
BOOL FASTCALL UITOOLS95_DrawFrameMenu(HDC dc, LPRECT r, UINT uFlags) { LOGFONTW lf; HFONT hFont, hOldFont; WCHAR Symbol; switch(uFlags & 0xff) { case DFCS_MENUARROWUP: Symbol = '5'; break; case DFCS_MENUARROWDOWN: Symbol = '6'; break; case DFCS_MENUARROW: Symbol = '8'; break; case DFCS_MENUARROWRIGHT: Symbol = 'w'; // FIXME: needs to confirm break; case DFCS_MENUBULLET: Symbol = 'h'; break; case DFCS_MENUCHECK: Symbol = 'a'; break; default: /* DbgPrint("Invalid menu; flags=0x%04x\n", uFlags); */ return FALSE; } /* acquire ressources only if valid menu */ RtlZeroMemory(&lf, sizeof(LOGFONTW)); lf.lfHeight = r->bottom - r->top; lf.lfWidth = 0; lf.lfWeight = FW_NORMAL; lf.lfCharSet = DEFAULT_CHARSET; RtlCopyMemory(lf.lfFaceName, L"Marlett", sizeof(L"Marlett")); hFont = GreCreateFontIndirectW(&lf); /* save font */ hOldFont = NtGdiSelectFont(dc, hFont); if ((uFlags & 0xff) == DFCS_MENUARROWUP || (uFlags & 0xff) == DFCS_MENUARROWDOWN ) { #if 0 if (uFlags & DFCS_INACTIVE) { /* draw shadow */ IntGdiSetTextColor(dc, IntGetSysColor(COLOR_BTNHIGHLIGHT)); GreTextOutW(dc, r->left + 1, r->top + 1, &Symbol, 1); } #endif IntGdiSetTextColor(dc, IntGetSysColor((uFlags & DFCS_INACTIVE) ? COLOR_BTNSHADOW : COLOR_BTNTEXT)); } /* draw selected symbol */ GreTextOutW(dc, r->left, r->top, &Symbol, 1); /* restore previous settings */ NtGdiSelectFont(dc, hOldFont); GreDeleteObject(hFont); return TRUE; }
BOOL FASTCALL UITOOLS95_DrawFrameCaption(HDC dc, LPRECT r, UINT uFlags) { LOGFONTW lf; HFONT hFont, hOldFont; COLORREF clrsave; RECT myr; INT bkmode; WCHAR Symbol; switch(uFlags & 0xff) { case DFCS_CAPTIONCLOSE: Symbol = 'r'; break; case DFCS_CAPTIONHELP: Symbol = 's'; break; case DFCS_CAPTIONMIN: Symbol = '0'; break; case DFCS_CAPTIONMAX: Symbol = '1'; break; case DFCS_CAPTIONRESTORE: Symbol = '2'; break; default: return FALSE; } IntDrawRectEdge(dc,r,(uFlags&DFCS_PUSHED) ? EDGE_SUNKEN : EDGE_RAISED, BF_RECT | BF_MIDDLE | BF_SOFT); RtlZeroMemory(&lf, sizeof(LOGFONTW)); UITOOLS_MakeSquareRect(r, &myr); myr.left += 1; myr.top += 1; myr.right -= 1; myr.bottom -= 1; if(uFlags & DFCS_PUSHED) RECTL_vOffsetRect(&myr,1,1); lf.lfHeight = myr.bottom - myr.top; lf.lfWidth = 0; lf.lfWeight = FW_NORMAL; lf.lfCharSet = DEFAULT_CHARSET; lf.lfQuality = NONANTIALIASED_QUALITY; RtlCopyMemory(lf.lfFaceName, L"Marlett", sizeof(L"Marlett")); hFont = GreCreateFontIndirectW(&lf); /* save font and text color */ hOldFont = NtGdiSelectFont(dc, hFont); clrsave = GreGetTextColor(dc); bkmode = GreGetBkMode(dc); /* set color and drawing mode */ IntGdiSetBkMode(dc, TRANSPARENT); if(uFlags & DFCS_INACTIVE) { /* draw shadow */ IntGdiSetTextColor(dc, IntGetSysColor(COLOR_BTNHIGHLIGHT)); GreTextOutW(dc, myr.left + 1, myr.top + 1, &Symbol, 1); } IntGdiSetTextColor(dc, IntGetSysColor((uFlags & DFCS_INACTIVE) ? COLOR_BTNSHADOW : COLOR_BTNTEXT)); /* draw selected symbol */ GreTextOutW(dc, myr.left, myr.top, &Symbol, 1); /* restore previous settings */ IntGdiSetTextColor(dc, clrsave); NtGdiSelectFont(dc, hOldFont); IntGdiSetBkMode(dc, bkmode); GreDeleteObject(hFont); return TRUE; }
BOOL FASTCALL UITOOLS95_DFC_ButtonCheckRadio(HDC dc, LPRECT r, UINT uFlags, BOOL Radio) { LOGFONTW lf; HFONT hFont, hOldFont; int i; WCHAR OutRight, OutLeft, InRight, InLeft, Center; if (Radio) { OutRight = 'j'; // Outer right OutLeft = 'k'; // Outer left InRight = 'l'; // inner left InLeft = 'm'; // inner right Center = 'n'; // center } else { OutRight = 'c'; // Outer right OutLeft = 'd'; // Outer left InRight = 'e'; // inner left InLeft = 'f'; // inner right Center = 'g'; // center } RtlZeroMemory(&lf, sizeof(LOGFONTW)); lf.lfHeight = r->top - r->bottom; lf.lfWidth = 0; lf.lfWeight = FW_NORMAL; lf.lfCharSet = DEFAULT_CHARSET; RtlCopyMemory(lf.lfFaceName, L"Marlett", sizeof(L"Marlett")); hFont = GreCreateFontIndirectW(&lf); hOldFont = NtGdiSelectFont(dc, hFont); if(Radio && ((uFlags & 0xff) == DFCS_BUTTONRADIOMASK)) { IntGdiSetBkMode(dc, OPAQUE); IntGdiSetTextColor(dc, IntGetSysColor(COLOR_WINDOWFRAME)); GreTextOutW(dc, r->left, r->top, &Center, 1); IntGdiSetBkMode(dc, TRANSPARENT); IntGdiSetTextColor(dc, IntGetSysColor(COLOR_WINDOWFRAME)); GreTextOutW(dc, r->left, r->top, &OutRight, 1); IntGdiSetTextColor(dc, IntGetSysColor(COLOR_WINDOWFRAME)); GreTextOutW(dc, r->left, r->top, &OutLeft, 1); } else { IntGdiSetBkMode(dc, TRANSPARENT); /* Center section, white for active, grey for inactive */ i= !(uFlags & (DFCS_INACTIVE|DFCS_PUSHED)) ? COLOR_WINDOW : COLOR_BTNFACE; IntGdiSetTextColor(dc, IntGetSysColor(i)); GreTextOutW(dc, r->left, r->top, &Center, 1); if(uFlags & (DFCS_FLAT | DFCS_MONO)) { IntGdiSetTextColor(dc, IntGetSysColor(COLOR_WINDOWFRAME)); GreTextOutW(dc, r->left, r->top, &OutRight, 1); GreTextOutW(dc, r->left, r->top, &OutLeft, 1); GreTextOutW(dc, r->left, r->top, &InRight, 1); GreTextOutW(dc, r->left, r->top, &InLeft, 1); } else { IntGdiSetTextColor(dc, IntGetSysColor(COLOR_BTNSHADOW)); GreTextOutW(dc, r->left, r->top, &OutRight, 1); IntGdiSetTextColor(dc, IntGetSysColor(COLOR_BTNHIGHLIGHT)); GreTextOutW(dc, r->left, r->top, &OutLeft, 1); IntGdiSetTextColor(dc, IntGetSysColor(COLOR_3DDKSHADOW)); GreTextOutW(dc, r->left, r->top, &InRight, 1); IntGdiSetTextColor(dc, IntGetSysColor(COLOR_3DLIGHT)); GreTextOutW(dc, r->left, r->top, &InLeft, 1); } } if(uFlags & DFCS_CHECKED) { WCHAR Check = (Radio) ? 'i' : 'b'; IntGdiSetTextColor(dc, IntGetSysColor(COLOR_WINDOWTEXT)); GreTextOutW(dc, r->left, r->top, &Check, 1); } IntGdiSetTextColor(dc, IntGetSysColor(COLOR_WINDOWTEXT)); NtGdiSelectFont(dc, hOldFont); GreDeleteObject(hFont); return TRUE; }
HDC FASTCALL UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags) { PWND Parent; ULONG DcxFlags; DCE* Dce = NULL; BOOL UpdateClipOrigin = FALSE; BOOL bUpdateVisRgn = TRUE; HDC hDC = NULL; PPROCESSINFO ppi; PLIST_ENTRY ListEntry; if (NULL == Wnd) { Flags &= ~DCX_USESTYLE; Flags |= DCX_CACHE; } if (Flags & DCX_PARENTCLIP) Flags |= DCX_CACHE; // When GetDC is called with hWnd nz, DCX_CACHE & _WINDOW are clear w _USESTYLE set. if (Flags & DCX_USESTYLE) { Flags &= ~(DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS | DCX_PARENTCLIP); if (!(Flags & DCX_WINDOW)) // Not window rectangle { if (Wnd->pcls->style & CS_PARENTDC) { Flags |= DCX_PARENTCLIP; } if (!(Flags & DCX_CACHE) && // Not on the cheap wine list. !(Wnd->pcls->style & CS_OWNDC) ) { if (!(Wnd->pcls->style & CS_CLASSDC)) // The window is not POWNED or has any CLASS, so we are looking for cheap wine. Flags |= DCX_CACHE; else { if (Wnd->pcls->pdce) hDC = ((PDCE)Wnd->pcls->pdce)->hDC; TRACE("We have CLASS!!\n"); } } if (Wnd->style & WS_CLIPSIBLINGS) { Flags |= DCX_CLIPSIBLINGS; } if (Wnd->style & WS_CLIPCHILDREN && !(Wnd->style & WS_MINIMIZE)) { Flags |= DCX_CLIPCHILDREN; } /* If minized with icon in the set, we are forced to be cheap! */ if (Wnd->style & WS_MINIMIZE && Wnd->pcls->spicn) { Flags |= DCX_CACHE; } } else { if (Wnd->style & WS_CLIPSIBLINGS) Flags |= DCX_CLIPSIBLINGS; Flags |= DCX_CACHE; } } if (Flags & DCX_WINDOW) Flags &= ~DCX_CLIPCHILDREN; if (Flags & DCX_NOCLIPCHILDREN) { Flags |= DCX_CACHE; Flags &= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN); } Parent = (Wnd ? Wnd->spwndParent : NULL); if (NULL == Wnd || !(Wnd->style & WS_CHILD) || NULL == Parent) { Flags &= ~DCX_PARENTCLIP; Flags |= DCX_CLIPSIBLINGS; } /* It seems parent clip is ignored when clipping siblings or children */ if (Flags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN)) Flags &= ~DCX_PARENTCLIP; if (Flags & DCX_PARENTCLIP) { if ((Wnd->style & WS_VISIBLE) && (Parent->style & WS_VISIBLE)) { Flags &= ~DCX_CLIPCHILDREN; if (Parent->style & WS_CLIPSIBLINGS) { Flags |= DCX_CLIPSIBLINGS; } } } // Window nz, check to see if we still own this or it is just cheap wine tonight. if (!(Flags & DCX_CACHE)) { if ( Wnd->head.pti != GetW32ThreadInfo()) Flags |= DCX_CACHE; // Ah~ Not Powned! Forced to be cheap~ } DcxFlags = Flags & DCX_CACHECOMPAREMASK; if (Flags & DCX_CACHE) { // Scan the cheap wine list for our match. DCE* DceEmpty = NULL; DCE* DceUnused = NULL; KeEnterCriticalRegion(); ListEntry = LEDce.Flink; while (ListEntry != &LEDce) { Dce = CONTAINING_RECORD(ListEntry, DCE, List); ListEntry = ListEntry->Flink; // // The way I understand this, you can have more than one DC per window. // Only one Owned if one was requested and saved and one Cached. // if ((Dce->DCXFlags & (DCX_CACHE | DCX_DCEBUSY)) == DCX_CACHE) { DceUnused = Dce; if (Dce->DCXFlags & DCX_DCEEMPTY) { DceEmpty = Dce; } else if (Dce->hwndCurrent == (Wnd ? Wnd->head.h : NULL) && ((Dce->DCXFlags & DCX_CACHECOMPAREMASK) == DcxFlags)) { UpdateClipOrigin = TRUE; break; } } Dce = NULL; // Loop issue? } KeLeaveCriticalRegion(); Dce = (DceEmpty == NULL) ? DceUnused : DceEmpty; if (Dce == NULL) { Dce = DceAllocDCE(NULL, DCE_CACHE_DC); } if (Dce == NULL) return NULL; Dce->hwndCurrent = (Wnd ? Wnd->head.h : NULL); Dce->pwndOrg = Dce->pwndClip = Wnd; } else // If we are here, we are POWNED or having CLASS. { KeEnterCriticalRegion(); ListEntry = LEDce.Flink; while (ListEntry != &LEDce) { Dce = CONTAINING_RECORD(ListEntry, DCE, List); ListEntry = ListEntry->Flink; // Skip Cache DCE entries. if (!(Dce->DCXFlags & DCX_CACHE)) { // Check for Window handle than HDC match for CLASS. if (Dce->hwndCurrent == Wnd->head.h) { bUpdateVisRgn = FALSE; break; } else if (Dce->hDC == hDC) break; } Dce = NULL; // Loop issue? } KeLeaveCriticalRegion(); if (Dce == NULL) { return(NULL); } if ( (Flags & (DCX_INTERSECTRGN|DCX_EXCLUDERGN)) && (Dce->DCXFlags & (DCX_INTERSECTRGN|DCX_EXCLUDERGN)) ) { DceDeleteClipRgn(Dce); } } // First time use hax, need to use DceAllocDCE during window display init. if (NULL == Dce) { return(NULL); } if (!GreIsHandleValid(Dce->hDC)) { ERR("FIXME: Got DCE with invalid hDC! %p\n", Dce->hDC); Dce->hDC = DceCreateDisplayDC(); /* FIXME: Handle error */ } Dce->DCXFlags = Flags | DCX_DCEBUSY; /* * Bump it up! This prevents the random errors in wine dce tests and with * proper bits set in DCX_CACHECOMPAREMASK. * Reference: * http://www.reactos.org/archives/public/ros-dev/2008-July/010498.html * http://www.reactos.org/archives/public/ros-dev/2008-July/010499.html */ RemoveEntryList(&Dce->List); InsertHeadList(&LEDce, &Dce->List); /* Introduced in rev 6691 and modified later. */ if ( (Flags & DCX_INTERSECTUPDATE) && !ClipRegion ) { Flags |= DCX_INTERSECTRGN | DCX_KEEPCLIPRGN; Dce->DCXFlags |= DCX_INTERSECTRGN | DCX_KEEPCLIPRGN; ClipRegion = Wnd->hrgnUpdate; bUpdateVisRgn = TRUE; } if (ClipRegion == HRGN_WINDOW) { if (!(Flags & DCX_WINDOW)) { Dce->hrgnClip = NtGdiCreateRectRgn( Wnd->rcClient.left, Wnd->rcClient.top, Wnd->rcClient.right, Wnd->rcClient.bottom); } else { Dce->hrgnClip = NtGdiCreateRectRgn( Wnd->rcWindow.left, Wnd->rcWindow.top, Wnd->rcWindow.right, Wnd->rcWindow.bottom); } Dce->DCXFlags &= ~DCX_KEEPCLIPRGN; bUpdateVisRgn = TRUE; } else if (ClipRegion != NULL) { if (Dce->hrgnClip != NULL) { ERR("Should not be called!!\n"); GreDeleteObject(Dce->hrgnClip); Dce->hrgnClip = NULL; } Dce->hrgnClip = ClipRegion; bUpdateVisRgn = TRUE; } if (IntGdiSetHookFlags(Dce->hDC, DCHF_VALIDATEVISRGN)) bUpdateVisRgn = TRUE; DceSetDrawable(Wnd, Dce->hDC, Flags, UpdateClipOrigin); if (bUpdateVisRgn) DceUpdateVisRgn(Dce, Wnd, Flags); if (Dce->DCXFlags & DCX_CACHE) { TRACE("ENTER!!!!!! DCX_CACHE!!!!!! hDC-> %p\n", Dce->hDC); // Need to set ownership so Sync dcattr will work. GreSetDCOwner(Dce->hDC, GDI_OBJ_HMGR_POWNED); Dce->ptiOwner = GetW32ThreadInfo(); // Set the temp owning } if ( Wnd && Wnd->ExStyle & WS_EX_LAYOUTRTL && !(Flags & DCX_KEEPLAYOUT) ) { NtGdiSetLayout(Dce->hDC, -1, LAYOUT_RTL); } if (Dce->DCXFlags & DCX_PROCESSOWNED) { ppi = PsGetCurrentProcessWin32Process(); ppi->W32PF_flags |= W32PF_OWNDCCLEANUP; Dce->ptiOwner = NULL; Dce->ppiOwner = ppi; } return(Dce->hDC); }
/* * Fills the CLIPOBJ and client rect of the WNDOBJ with the data from the given WND */ BOOLEAN FASTCALL IntEngWndUpdateClipObj( WNDGDI *WndObjInt, PWND Window) { HRGN hVisRgn; PROSRGNDATA visRgn; CLIPOBJ *ClipObj = NULL; CLIPOBJ *OldClipObj; DPRINT("IntEngWndUpdateClipObj\n"); hVisRgn = VIS_ComputeVisibleRegion(Window, TRUE, TRUE, TRUE); if (hVisRgn != NULL) { NtGdiOffsetRgn(hVisRgn, Window->rcClient.left, Window->rcClient.top); visRgn = RGNOBJAPI_Lock(hVisRgn, NULL); if (visRgn != NULL) { if (visRgn->rdh.nCount > 0) { ClipObj = IntEngCreateClipRegion(visRgn->rdh.nCount, visRgn->Buffer, &visRgn->rdh.rcBound); DPRINT("Created visible region with %lu rects\n", visRgn->rdh.nCount); DPRINT(" BoundingRect: %d, %d %d, %d\n", visRgn->rdh.rcBound.left, visRgn->rdh.rcBound.top, visRgn->rdh.rcBound.right, visRgn->rdh.rcBound.bottom); { ULONG i; for (i = 0; i < visRgn->rdh.nCount; i++) { DPRINT(" Rect #%lu: %ld,%ld %ld,%ld\n", i+1, visRgn->Buffer[i].left, visRgn->Buffer[i].top, visRgn->Buffer[i].right, visRgn->Buffer[i].bottom); } } } RGNOBJAPI_Unlock(visRgn); } else { DPRINT1("Warning: Couldn't lock visible region of window DC\n"); } GreDeleteObject(hVisRgn); } else { DPRINT1("Warning: VIS_ComputeVisibleRegion failed!\n"); } if (ClipObj == NULL) { /* Fall back to client rect */ ClipObj = IntEngCreateClipRegion(1, &Window->rcClient, &Window->rcClient); } if (ClipObj == NULL) { DPRINT1("Warning: IntEngCreateClipRegion() failed!\n"); return FALSE; } RtlCopyMemory(&WndObjInt->WndObj.coClient, ClipObj, sizeof (CLIPOBJ)); RtlCopyMemory(&WndObjInt->WndObj.rclClient, &Window->rcClient, sizeof (RECT)); OldClipObj = InterlockedExchangePointer((PVOID*)&WndObjInt->ClientClipObj, ClipObj); if (OldClipObj != NULL) IntEngDeleteClipRegion(OldClipObj); return TRUE; }
BOOLEAN FASTCALL IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, BOOLEAN bForce) { if(CurIcon->CURSORF_flags & CURSORF_CURRENT) { /* Mark the object as destroyed, and fail, as per tests */ TRACE("Cursor is current, marking as destroyed.\n"); UserDeleteObject(CurIcon->head.h, TYPE_CURSOR); return FALSE; } if(CurIcon->head.ppi != PsGetCurrentProcessWin32Process()) { /* This object doesn't belong to the current process */ WARN("Trying to delete foreign cursor!\n"); UserDereferenceObject(CurIcon); EngSetLastError(ERROR_DESTROY_OBJECT_OF_OTHER_THREAD); return FALSE; } /* Do not destroy it if it is shared. (And we're not forced to) */ if((CurIcon->CURSORF_flags & CURSORF_LRSHARED) && !bForce) { /* Tests show this is a valid call */ WARN("Trying to destroy shared cursor!\n"); UserDereferenceObject(CurIcon); return TRUE; } if(!(CurIcon->CURSORF_flags & CURSORF_ACON)) { HBITMAP bmpMask = CurIcon->hbmMask; HBITMAP bmpColor = CurIcon->hbmColor; HBITMAP bmpAlpha = CurIcon->hbmAlpha; /* Delete bitmaps */ if (bmpMask) { GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED); GreDeleteObject(bmpMask); CurIcon->hbmMask = NULL; } if (bmpColor) { GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED); GreDeleteObject(bmpColor); CurIcon->hbmColor = NULL; } if (bmpAlpha) { GreSetObjectOwner(bmpAlpha, GDI_OBJ_HMGR_POWNED); GreDeleteObject(bmpAlpha); CurIcon->hbmAlpha = NULL; } } else { PACON AniCurIcon = (PACON)CurIcon; UINT i; for(i = 0; i < AniCurIcon->cpcur; i++) IntDestroyCurIconObject(AniCurIcon->aspcur[i], TRUE); ExFreePoolWithTag(AniCurIcon->aspcur, USERTAG_CURSOR); } if (CurIcon->CURSORF_flags & CURSORF_LRSHARED) { if (!IS_INTRESOURCE(CurIcon->strName.Buffer)) ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING); if (CurIcon->atomModName) RtlDeleteAtomFromAtomTable(gAtomTable, CurIcon->atomModName); CurIcon->strName.Buffer = NULL; CurIcon->atomModName = 0; } /* We were given a pointer, no need to keep the reference any longer! */ UserDereferenceObject(CurIcon); return UserDeleteObject(CurIcon->head.h, TYPE_CURSOR); }