}
BOOL FASTCALL
-IntValidateParent(PWND Child, HRGN hValidateRgn, BOOL Recurse)
+IntValidateParent(PWND Child, PREGION ValidateRgn, BOOL Recurse)
{
PWND ParentWnd = Child;
return FALSE;
IntInvalidateWindows( ParentWnd,
- hValidateRgn,
+ ValidateRgn,
RDW_VALIDATE | RDW_NOCHILDREN);
}
VOID FASTCALL
IntSendSyncPaint(PWND Wnd, ULONG Flags)
{
- PTHREADINFO ptiCur;
- PUSER_MESSAGE_QUEUE MessageQueue;
+ PTHREADINFO ptiCur, ptiWnd;
PUSER_SENT_MESSAGE Message;
PLIST_ENTRY Entry;
BOOL bSend = TRUE;
- MessageQueue = Wnd->head.pti->MessageQueue;
+ ptiWnd = Wnd->head.pti;
ptiCur = PsGetCurrentThreadWin32Thread();
/*
Not the current thread, Wnd is in send Nonclient paint also in send erase background and it is visiable.
{
// For testing, if you see this, break out the Champagne and have a party!
ERR("SendSyncPaint Wnd in State!\n");
- if (!IsListEmpty(&MessageQueue->SentMessagesListHead))
+ if (!IsListEmpty(&ptiWnd->SentMessagesListHead))
{
// Scan sent queue messages to see if we received sync paint messages.
- Entry = MessageQueue->SentMessagesListHead.Flink;
+ Entry = ptiWnd->SentMessagesListHead.Flink;
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
do
{
Entry = Message->ListEntry.Flink;
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
}
- while (Entry != &MessageQueue->SentMessagesListHead);
+ while (Entry != &ptiWnd->SentMessagesListHead);
}
if (bSend)
{
HRGN hRgnWindow;
if (Client)
- hRgnWindow = IntSysCreateRectRgnIndirect(&Wnd->rcClient);
+ {
+ hRgnWindow = NtGdiCreateRectRgn(
+ Wnd->rcClient.left,
+ Wnd->rcClient.top,
+ Wnd->rcClient.right,
+ Wnd->rcClient.bottom);
+ }
else
- hRgnWindow = IntSysCreateRectRgnIndirect(&Wnd->rcWindow);
+ {
+ hRgnWindow = NtGdiCreateRectRgn(
+ Wnd->rcWindow.left,
+ Wnd->rcWindow.top,
+ Wnd->rcWindow.right,
+ Wnd->rcWindow.bottom);
+ }
if (Wnd->hrgnClip != NULL && !(Wnd->style & WS_MINIMIZE))
{
Window->state &= ~WNDS_UPDATEDIRTY;
Window->hrgnUpdate = NULL;
if (!(Window->state & WNDS_INTERNALPAINT))
- MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
+ MsqDecPaintCountQueue(Window->head.pti);
}
}
{
if (Wnd->hrgnUpdate)
{
- if (!IntValidateParent(Wnd, Wnd->hrgnUpdate, Recurse))
- return;
+ PREGION RgnUpdate = RGNOBJAPI_Lock(Wnd->hrgnUpdate, NULL);
+ if (RgnUpdate)
+ {
+ if (!IntValidateParent(Wnd, RgnUpdate, Recurse))
+ {
+ RGNOBJAPI_Unlock(RgnUpdate);
+ return;
+ }
+ RGNOBJAPI_Unlock(RgnUpdate);
+ }
}
if (Flags & RDW_UPDATENOW)
UserDerefObjectCo(Wnd);
}
}
- ExFreePool(List);
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
}
}
}
* co_WinPosSetWindowPos, IntValidateParent, co_UserRedrawWindow.
*/
VOID FASTCALL
-IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
+IntInvalidateWindows(PWND Wnd, PREGION Rgn, ULONG Flags)
{
INT RgnType;
BOOL HadPaintMessage;
*/
if (0 != (Flags & RDW_INVALIDATE) && 0 == (Flags & RDW_FRAME))
{
- HRGN hRgnClient;
+ PREGION RgnClient;
- hRgnClient = IntSysCreateRectRgnIndirect(&Wnd->rcClient);
- RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnClient, RGN_AND);
- GreDeleteObject(hRgnClient);
+ RgnClient = IntSysCreateRectpRgnIndirect(&Wnd->rcClient);
+ if (RgnClient)
+ {
+ RgnType = IntGdiCombineRgn(Rgn, Rgn, RgnClient, RGN_AND);
+ REGION_Delete(RgnClient);
+ }
}
/*
if (!Wnd->hrgnClip || (Wnd->style & WS_MINIMIZE))
{
- HRGN hRgnWindow;
-
- hRgnWindow = IntSysCreateRectRgnIndirect(&Wnd->rcWindow);
- RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnWindow, RGN_AND);
- GreDeleteObject(hRgnWindow);
+ PREGION RgnWindow = IntSysCreateRectpRgnIndirect(&Wnd->rcWindow);
+ if (RgnWindow)
+ {
+ RgnType = IntGdiCombineRgn(Rgn, Rgn, RgnWindow, RGN_AND);
+ REGION_Delete(RgnWindow);
+ }
}
else
{
- NtGdiOffsetRgn( hRgn,
- -Wnd->rcWindow.left,
- -Wnd->rcWindow.top);
- RgnType = NtGdiCombineRgn(hRgn, hRgn, Wnd->hrgnClip, RGN_AND);
- NtGdiOffsetRgn( hRgn,
- Wnd->rcWindow.left,
- Wnd->rcWindow.top);
+ PREGION RgnClip = RGNOBJAPI_Lock(Wnd->hrgnClip, NULL);
+ if (RgnClip)
+ {
+ IntGdiOffsetRgn( Rgn,
+ -Wnd->rcWindow.left,
+ -Wnd->rcWindow.top);
+ RgnType = IntGdiCombineRgn(Rgn, Rgn, RgnClip, RGN_AND);
+ IntGdiOffsetRgn( Rgn,
+ Wnd->rcWindow.left,
+ Wnd->rcWindow.top);
+ RGNOBJAPI_Unlock(RgnClip);
+ }
}
/*
if (Flags & RDW_INVALIDATE && RgnType != NULLREGION)
{
+ PREGION RgnUpdate;
+
Wnd->state &= ~WNDS_NONCPAINT;
/* If not the same thread set it dirty. */
if (Wnd->hrgnUpdate == NULL)
{
- Wnd->hrgnUpdate = IntSysCreateRectRgn(0, 0, 0, 0);
+ Wnd->hrgnUpdate = NtGdiCreateRectRgn(0, 0, 0, 0);
IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_PUBLIC);
}
- if (NtGdiCombineRgn(Wnd->hrgnUpdate, Wnd->hrgnUpdate,
- hRgn, RGN_OR) == NULLREGION)
+ RgnUpdate = RGNOBJAPI_Lock(Wnd->hrgnUpdate, NULL);
+ if (RgnUpdate)
{
- IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
- GreDeleteObject(Wnd->hrgnUpdate);
- Wnd->hrgnUpdate = NULL;
+ RgnType = IntGdiCombineRgn(RgnUpdate, RgnUpdate, Rgn, RGN_OR);
+ RGNOBJAPI_Unlock(RgnUpdate);
+ if (RgnType == NULLREGION)
+ {
+ IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
+ GreDeleteObject(Wnd->hrgnUpdate);
+ Wnd->hrgnUpdate = NULL;
+ }
}
Flags |= RDW_FRAME; // For children.
}
if (Flags & RDW_VALIDATE && RgnType != NULLREGION)
{
- if (Flags & RDW_NOFRAME)
+ if (Flags & RDW_NOFRAME)
Wnd->state &= ~WNDS_SENDNCPAINT;
if (Flags & RDW_NOERASE)
Wnd->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
if (Wnd->hrgnUpdate != NULL)
{
- if (NtGdiCombineRgn(Wnd->hrgnUpdate, Wnd->hrgnUpdate,
- hRgn, RGN_DIFF) == NULLREGION)
- {
- IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
- GreDeleteObject(Wnd->hrgnUpdate);
- Wnd->hrgnUpdate = NULL;
- }
+ PREGION RgnUpdate = RGNOBJAPI_Lock(Wnd->hrgnUpdate, NULL);
+
+ if (RgnUpdate)
+ {
+ RgnType = IntGdiCombineRgn(RgnUpdate, RgnUpdate, Rgn, RGN_DIFF);
+ RGNOBJAPI_Unlock(RgnUpdate);
+
+ if(RgnType == NULLREGION)
+ {
+ IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
+ GreDeleteObject(Wnd->hrgnUpdate);
+ Wnd->hrgnUpdate = NULL;
+ }
+ }
}
if (Wnd->hrgnUpdate == NULL)
/*
* Recursive call to update children hrgnUpdate
*/
- HRGN hRgnTemp = IntSysCreateRectRgn(0, 0, 0, 0);
- NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY);
- IntInvalidateWindows(Child, hRgnTemp, Flags);
- GreDeleteObject(hRgnTemp);
+ PREGION RgnTemp = IntSysCreateRectpRgn(0, 0, 0, 0);
+ if (RgnTemp)
+ {
+ IntGdiCombineRgn(RgnTemp, Rgn, 0, RGN_COPY);
+ IntInvalidateWindows(Child, RgnTemp, Flags);
+ REGION_Delete(RgnTemp);
+ }
}
}
}
if (HadPaintMessage != IntIsWindowDirty(Wnd))
{
if (HadPaintMessage)
- MsqDecPaintCountQueue(Wnd->head.pti->MessageQueue);
+ MsqDecPaintCountQueue(Wnd->head.pti);
else
- MsqIncPaintCountQueue(Wnd->head.pti->MessageQueue);
+ MsqIncPaintCountQueue(Wnd->head.pti);
}
TRACE("IntInvalidateWindows exit\n");
}
co_UserRedrawWindow(
PWND Window,
const RECTL* UpdateRect,
- HRGN UpdateRgn,
+ PREGION UpdateRgn,
ULONG Flags)
{
- HRGN hRgn = NULL;
+ PREGION TmpRgn = NULL;
TRACE("co_UserRedrawWindow start\n");
/*
if (Flags & (RDW_INVALIDATE | RDW_VALIDATE)) // Both are OKAY!
{
- if (UpdateRgn != NULL)
+ if (UpdateRgn)
{
- hRgn = IntSysCreateRectRgn(0, 0, 0, 0);
- if (NtGdiCombineRgn(hRgn, UpdateRgn, NULL, RGN_COPY) == NULLREGION)
- {
- GreDeleteObject(hRgn);
- hRgn = NULL;
- }
- else
- NtGdiOffsetRgn(hRgn, Window->rcClient.left, Window->rcClient.top);
+ TmpRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
+ if (IntGdiCombineRgn(TmpRgn, UpdateRgn, NULL, RGN_COPY) == NULLREGION)
+ {
+ REGION_Delete(TmpRgn);
+ TmpRgn = NULL;
+ }
+ else
+ {
+ IntGdiOffsetRgn(TmpRgn, Window->rcClient.left, Window->rcClient.top);
+ }
}
else if (UpdateRect != NULL)
{
if (!RECTL_bIsEmptyRect(UpdateRect))
{
- hRgn = IntSysCreateRectRgnIndirect((RECTL *)UpdateRect);
- NtGdiOffsetRgn(hRgn, Window->rcClient.left, Window->rcClient.top);
+ TmpRgn = IntSysCreateRectpRgnIndirect(UpdateRect);
+ IntGdiOffsetRgn(TmpRgn, Window->rcClient.left, Window->rcClient.top);
}
}
else if ((Flags & (RDW_INVALIDATE | RDW_FRAME)) == (RDW_INVALIDATE | RDW_FRAME) ||
(Flags & (RDW_VALIDATE | RDW_NOFRAME)) == (RDW_VALIDATE | RDW_NOFRAME))
{
if (!RECTL_bIsEmptyRect(&Window->rcWindow))
- hRgn = IntSysCreateRectRgnIndirect(&Window->rcWindow);
+ TmpRgn = IntSysCreateRectpRgnIndirect(&Window->rcWindow);
}
else
{
if (!RECTL_bIsEmptyRect(&Window->rcClient))
- hRgn = IntSysCreateRectRgnIndirect(&Window->rcClient);
+ TmpRgn = IntSysCreateRectpRgnIndirect(&Window->rcClient);
}
}
*/
if (Flags & (RDW_INVALIDATE | RDW_VALIDATE | RDW_INTERNALPAINT | RDW_NOINTERNALPAINT) &&
- hRgn != NULL)
+ TmpRgn != NULL)
{
- IntInvalidateWindows(Window, hRgn, Flags);
+ IntInvalidateWindows(Window, TmpRgn, Flags);
}
/*
* Cleanup ;-)
*/
- if (hRgn != NULL)
+ if (TmpRgn != NULL)
{
- GreDeleteObject(hRgn);
+ REGION_Delete(TmpRgn);
}
TRACE("co_UserRedrawWindow exit\n");
if (Message->hwnd == NULL)
{
- ERR("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found! Counts %d\n",Thread->cPaintsReady);
+ ERR("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found! Counts %u\n",Thread->cPaintsReady);
/* Hack to stop spamming the debuglog ! */
Thread->cPaintsReady = 0;
return FALSE;
{
PaintWnd->state &= ~WNDS_INTERNALPAINT;
if (!PaintWnd->hrgnUpdate)
- MsqDecPaintCountQueue(Thread->MessageQueue);
+ MsqDecPaintCountQueue(Thread);
}
PaintWnd->state2 &= ~WNDS2_WMPAINTSENT;
PaintWnd->state &= ~WNDS_UPDATEDIRTY;
if (Window->hrgnUpdate != NULL)
{
- MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
+ MsqDecPaintCountQueue(Window->head.pti);
GdiGetClipBox(Ps->hdc, &Ps->rcPaint);
IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
/* The region is part of the dc now and belongs to the process! */
else
{
if (Window->state & WNDS_INTERNALPAINT)
- MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
+ MsqDecPaintCountQueue(Window->head.pti);
IntGetClientRect(Window, &Ps->rcPaint);
}
for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
{
if (Child->hrgnUpdate == NULL && Child->state & WNDS_SENDNCPAINT) // Helped fixing test_redrawnow.
- IntInvalidateWindows(Child, Window->hrgnUpdate, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
+ IntInvalidateWindows(Child, NULL, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
}
}
RETURN(FALSE);
}
+ UserRefObjectCo(Window, &Ref); // Here for the exception.
+
_SEH2_TRY
{
ProbeForRead(pUnsafePs, sizeof(*pUnsafePs), 1);
RETURN(FALSE);
}
- UserRefObjectCo(Window, &Ref);
-
RETURN(IntEndPaint(Window, &Ps));
CLEANUP:
if (!Ret) goto Exit;
- if (!( pWnd = (PWND)UserGetObject(gHandleTable, finfo.hwnd, otWindow)) ||
+ if (!( pWnd = (PWND)UserGetObject(gHandleTable, finfo.hwnd, TYPE_WINDOW)) ||
finfo.cbSize != sizeof(FLASHWINFO) ||
finfo.dwFlags & ~(FLASHW_ALL|FLASHW_TIMER|FLASHW_TIMERNOFG) )
{
}
INT FASTCALL
-co_UserGetUpdateRgn(PWND Window, HRGN hRgn, BOOL bErase)
+co_UserGetUpdateRgn(PWND Window, PREGION Rgn, BOOL bErase)
{
- int RegionType;
- RECTL Rect;
+ int RegionType;
+ RECTL Rect;
+ PREGION UpdateRgn;
- ASSERT_REFS_CO(Window);
+ ASSERT_REFS_CO(Window);
- Window->state &= ~WNDS_UPDATEDIRTY;
+ Window->state &= ~WNDS_UPDATEDIRTY;
- if (Window->hrgnUpdate == NULL)
- {
- RegionType = (NtGdiSetRectRgn(hRgn, 0, 0, 0, 0) ? NULLREGION : ERROR);
- }
- else
- {
- Rect = Window->rcClient;
- IntIntersectWithParents(Window, &Rect);
- NtGdiSetRectRgn(hRgn, Rect.left, Rect.top, Rect.right, Rect.bottom);
- RegionType = NtGdiCombineRgn(hRgn, hRgn, Window->hrgnUpdate, RGN_AND);
- NtGdiOffsetRgn(hRgn, -Window->rcClient.left, -Window->rcClient.top);
- }
+ if (Window->hrgnUpdate == NULL)
+ {
+ REGION_SetRectRgn(Rgn, 0, 0, 0, 0);
+ return NULLREGION;
+ }
+
+ UpdateRgn = RGNOBJAPI_Lock(Window->hrgnUpdate, NULL);
+ if (!UpdateRgn)
+ return ERROR;
+
+ Rect = Window->rcClient;
+ IntIntersectWithParents(Window, &Rect);
+ REGION_SetRectRgn(Rgn, Rect.left, Rect.top, Rect.right, Rect.bottom);
+ RegionType = IntGdiCombineRgn(Rgn, Rgn, UpdateRgn, RGN_AND);
+ IntGdiOffsetRgn(Rgn, -Window->rcClient.left, -Window->rcClient.top);
+ RGNOBJAPI_Unlock(UpdateRgn);
if (bErase && RegionType != NULLREGION && RegionType != ERROR)
{
PWND Window;
INT ret;
USER_REFERENCE_ENTRY Ref;
+ PREGION Rgn = NULL;
TRACE("Enter NtUserGetUpdateRgn\n");
UserEnterExclusive();
RETURN(ERROR);
}
+ /* Use a system region, we can't hold GDI locks when doing roundtrips to user mode */
+ Rgn = IntSysCreateRectpRgn(0, 0, 0, 0);
+ if (!Rgn)
+ RETURN(ERROR);
+
UserRefObjectCo(Window, &Ref);
- ret = co_UserGetUpdateRgn(Window, hRgn, bErase);
+ ret = co_UserGetUpdateRgn(Window, Rgn, bErase);
UserDerefObjectCo(Window);
RETURN(ret);
CLEANUP:
+ if (Rgn && (_ret_ != ERROR))
+ {
+ PREGION TheRgn = RGNOBJAPI_Lock(hRgn, NULL);
+ if (!TheRgn)
+ {
+ EngSetLastError(ERROR_INVALID_HANDLE);
+ _ret_ = ERROR;
+ }
+ IntGdiCombineRgn(TheRgn, Rgn, NULL, RGN_COPY);
+ RGNOBJAPI_Unlock(TheRgn);
+ }
+
+ if (Rgn)
+ REGION_Delete(Rgn);
+
TRACE("Leave NtUserGetUpdateRgn, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
BOOL Ret;
USER_REFERENCE_ENTRY Ref;
NTSTATUS Status = STATUS_SUCCESS;
+ PREGION RgnUpdate = NULL;
DECLARE_RETURN(BOOL);
TRACE("Enter NtUserRedrawWindow\n");
RETURN( FALSE);
}
+ /* We can't hold lock on GDI obects while doing roundtrips to user mode,
+ * so use a copy instead */
+ if (hrgnUpdate)
+ {
+ PREGION RgnTemp;
+
+ RgnUpdate = IntSysCreateRectpRgn(0, 0, 0, 0);
+ if (!RgnUpdate)
+ {
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ RETURN(FALSE);
+ }
+
+ RgnTemp = RGNOBJAPI_Lock(hrgnUpdate, NULL);
+ if (!RgnTemp)
+ {
+ EngSetLastError(ERROR_INVALID_HANDLE);
+ RETURN(FALSE);
+ }
+ IntGdiCombineRgn(RgnUpdate, RgnTemp, NULL, RGN_COPY);
+ RGNOBJAPI_Unlock(RgnTemp);
+ }
+
UserRefObjectCo(Wnd, &Ref);
Ret = co_UserRedrawWindow( Wnd,
lprcUpdate ? &SafeUpdateRect : NULL,
- hrgnUpdate,
+ RgnUpdate,
flags);
UserDerefObjectCo(Wnd);
RETURN( Ret);
CLEANUP:
+ if (RgnUpdate)
+ REGION_Delete(RgnUpdate);
TRACE("Leave NtUserRedrawWindow, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
INT dy,
const RECTL *prcScroll,
const RECTL *prcClip,
- HRGN hrgnUpdate,
+ PREGION RgnUpdate,
RECTL *prcUpdate)
{
PDC pDC;
/* Calculate the region that was invalidated by moving or
could not be copied, because it was not visible */
- if (hrgnUpdate || prcUpdate)
+ if (RgnUpdate || prcUpdate)
{
- HRGN hrgnOwn, hrgnTmp;
- PREGION prgnTmp;
+ PREGION RgnOwn, RgnTmp;
pDC = DC_LockDc(hDC);
if (!pDC)
rcDst = rcScroll;
RECTL_vOffsetRect(&rcDst, dx, dy);
RECTL_bIntersectRect(&rcDst, &rcDst, &rcClip);
- if (hrgnUpdate)
+ if (RgnUpdate)
{
- hrgnOwn = hrgnUpdate;
- if (!NtGdiSetRectRgn(hrgnOwn, rcDst.left, rcDst.top, rcDst.right, rcDst.bottom))
- {
- DC_UnlockDc(pDC);
- return ERROR;
- }
+ RgnOwn = RgnUpdate;
+ REGION_SetRectRgn(RgnOwn, rcDst.left, rcDst.top, rcDst.right, rcDst.bottom);
}
else
{
- hrgnOwn = IntSysCreateRectRgnIndirect(&rcDst);
+ RgnOwn = IntSysCreateRectpRgnIndirect(&rcDst);
}
/* Add the source rect */
- hrgnTmp = IntSysCreateRectRgnIndirect(&rcSrc);
- NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_OR);
+ RgnTmp = IntSysCreateRectpRgnIndirect(&rcSrc);
+ IntGdiCombineRgn(RgnOwn, RgnOwn, RgnTmp, RGN_OR);
/* Substract the part of the dest that was visible in source */
- prgnTmp = RGNOBJAPI_Lock(hrgnTmp, NULL);
- IntGdiCombineRgn(prgnTmp, prgnTmp, pDC->prgnVis, RGN_AND);
- RGNOBJAPI_Unlock(prgnTmp);
- NtGdiOffsetRgn(hrgnTmp, dx, dy);
- Result = NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_DIFF);
+ IntGdiCombineRgn(RgnTmp, RgnTmp, pDC->prgnVis, RGN_AND);
+ IntGdiOffsetRgn(RgnTmp, dx, dy);
+ Result = IntGdiCombineRgn(RgnOwn, RgnOwn, RgnTmp, RGN_DIFF);
/* DO NOT Unlock DC while messing with prgnVis! */
DC_UnlockDc(pDC);
- GreDeleteObject(hrgnTmp);
+ REGION_Delete(RgnTmp);
if (prcUpdate)
{
- IntGdiGetRgnBox(hrgnOwn, prcUpdate);
+ REGION_GetRgnBox(RgnOwn, prcUpdate);
}
- if (!hrgnUpdate)
+ if (!RgnUpdate)
{
- GreDeleteObject(hrgnOwn);
+ REGION_Delete(RgnOwn);
}
}
else
RECTL rcScroll, rcClip, rcUpdate;
NTSTATUS Status = STATUS_SUCCESS;
DWORD Result;
+ PREGION RgnUpdate = NULL;
TRACE("Enter NtUserScrollDC\n");
UserEnterExclusive();
RETURN(FALSE);
}
+ if (hrgnUpdate)
+ {
+ RgnUpdate = RGNOBJAPI_Lock(hrgnUpdate, NULL);
+ if (!RgnUpdate)
+ RETURN(FALSE);
+ }
+
Result = UserScrollDC( hDC,
dx,
dy,
prcUnsafeScroll? &rcScroll : 0,
prcUnsafeClip? &rcClip : 0,
- hrgnUpdate,
+ RgnUpdate,
prcUnsafeUpdate? &rcUpdate : NULL);
if(Result == ERROR)
{
RETURN(TRUE);
CLEANUP:
- TRACE("Leave NtUserScrollDC, ret=%i\n",_ret_);
+ if (RgnUpdate)
+ RGNOBJAPI_Unlock(RgnUpdate);
+ TRACE("Leave NtUserScrollDC, ret=%lu\n",_ret_);
UserLeave();
END_CLEANUP;
}
INT Result;
PWND Window = NULL, CaretWnd;
HDC hDC;
- HRGN hrgnOwn = NULL, hrgnTemp, hrgnWinupd = NULL;
+ PREGION RgnUpdate = NULL, RgnTemp, RgnWinupd = NULL;
HWND hwndCaret;
DWORD dcxflags = 0;
int rdw_flags;
- BOOL bOwnRgn = TRUE;
NTSTATUS Status = STATUS_SUCCESS;
DECLARE_RETURN(DWORD);
USER_REFERENCE_ENTRY Ref, CaretRef;
RETURN(NULLREGION);
}
+ /* We must use a copy of the region, as we can't hold an exclusive lock
+ * on it while doing callouts to user-mode */
+ RgnUpdate = IntSysCreateRectpRgn(0, 0, 0, 0);
+ if(!RgnUpdate)
+ {
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ RETURN(ERROR);
+ }
+
if (hrgnUpdate)
{
- hrgnOwn = hrgnUpdate;
- bOwnRgn = FALSE;
+ RgnTemp = RGNOBJAPI_Lock(hrgnUpdate, NULL);
+ if (!RgnTemp)
+ {
+ EngSetLastError(ERROR_INVALID_HANDLE);
+ RETURN(ERROR);
+ }
+ IntGdiCombineRgn(RgnUpdate, RgnTemp, NULL, RGN_COPY);
+ RGNOBJAPI_Unlock(RgnTemp);
}
- else
- hrgnOwn = IntSysCreateRectRgn(0, 0, 0, 0);
/* ScrollWindow uses the window DC, ScrollWindowEx doesn't */
if (flags & SW_SCROLLWNDDCE)
dcxflags = DCX_USESTYLE;
if (!(Window->pcls->style & (CS_OWNDC|CS_CLASSDC)))
- dcxflags |= DCX_CACHE; // AH??? wine~ If not Powned or with Class go Cheap!
+ dcxflags |= DCX_CACHE; // AH??? wine~ If not Powned or with Class go Cheap!
if (flags & SW_SCROLLCHILDREN && Window->style & WS_CLIPCHILDREN)
dcxflags |= DCX_CACHE|DCX_NOCLIPCHILDREN;
Result = UserScrollDC( hDC,
dx,
dy,
- &rcScroll,
- &rcClip,
- hrgnOwn,
+ &rcScroll,
+ &rcClip,
+ RgnUpdate,
prcUnsafeUpdate? &rcUpdate : NULL);
UserReleaseDC(Window, hDC, FALSE);
* the scroll. Keep a copy in hrgnWinupd to be added to hrngUpdate at the end.
*/
- hrgnTemp = IntSysCreateRectRgn(0, 0, 0, 0);
- if (co_UserGetUpdateRgn(Window, hrgnTemp, FALSE) != NULLREGION)
+ RgnTemp = IntSysCreateRectpRgn(0, 0, 0, 0);
+ if (!RgnTemp)
+ {
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ RETURN(ERROR);
+ }
+
+ if (co_UserGetUpdateRgn(Window, RgnTemp, FALSE) != NULLREGION)
{
- HRGN hrgnClip = IntSysCreateRectRgnIndirect(&rcClip);
- if (!bOwnRgn)
+ PREGION RgnClip = IntSysCreateRectpRgnIndirect(&rcClip);
+ if (RgnClip)
{
- hrgnWinupd = IntSysCreateRectRgn( 0, 0, 0, 0);
- NtGdiCombineRgn( hrgnWinupd, hrgnTemp, 0, RGN_COPY);
+ if (hrgnUpdate)
+ {
+ RgnWinupd = IntSysCreateRectpRgn( 0, 0, 0, 0);
+ IntGdiCombineRgn( RgnWinupd, RgnTemp, 0, RGN_COPY);
+ }
+ IntGdiOffsetRgn(RgnTemp, dx, dy);
+ IntGdiCombineRgn(RgnTemp, RgnTemp, RgnClip, RGN_AND);
+ if (hrgnUpdate)
+ IntGdiCombineRgn( RgnWinupd, RgnWinupd, RgnTemp, RGN_OR );
+ co_UserRedrawWindow(Window, NULL, RgnTemp, rdw_flags );
+ REGION_Delete(RgnClip);
}
- NtGdiOffsetRgn(hrgnTemp, dx, dy);
- NtGdiCombineRgn(hrgnTemp, hrgnTemp, hrgnClip, RGN_AND);
- if (!bOwnRgn) NtGdiCombineRgn( hrgnWinupd, hrgnWinupd, hrgnTemp, RGN_OR );
- co_UserRedrawWindow(Window, NULL, hrgnTemp, rdw_flags );
- GreDeleteObject(hrgnClip);
}
- GreDeleteObject(hrgnTemp);
+ REGION_Delete(RgnTemp);
if (flags & SW_SCROLLCHILDREN)
{
if (flags & (SW_INVALIDATE | SW_ERASE))
{
- co_UserRedrawWindow(Window, NULL, hrgnOwn, rdw_flags |
+ co_UserRedrawWindow(Window, NULL, RgnUpdate, rdw_flags |
((flags & SW_ERASE) ? RDW_ERASENOW : 0) |
((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0));
}
RETURN(Result);
CLEANUP:
- if (hrgnWinupd && !bOwnRgn)
+ if (hrgnUpdate && (_ret_ != ERROR))
{
- NtGdiCombineRgn( hrgnOwn, hrgnOwn, hrgnWinupd, RGN_OR);
- GreDeleteObject(hrgnWinupd);
+ /* Give everything back to the caller */
+ RgnTemp = RGNOBJAPI_Lock(hrgnUpdate, NULL);
+ /* The handle should still be valid */
+ ASSERT(RgnTemp);
+ if (RgnWinupd)
+ IntGdiCombineRgn(RgnTemp, RgnUpdate, RgnWinupd, RGN_OR);
+ else
+ IntGdiCombineRgn(RgnTemp, RgnUpdate, NULL, RGN_COPY);
+ RGNOBJAPI_Unlock(RgnTemp);
}
- if (hrgnOwn && !hrgnUpdate)
+ if (RgnWinupd)
{
- GreDeleteObject(hrgnOwn);
+ REGION_Delete(RgnWinupd);
+ }
+
+ if (RgnUpdate)
+ {
+ REGION_Delete(RgnUpdate);
}
if (Window)
UserDerefObjectCo(Window);
- TRACE("Leave NtUserScrollWindowEx, ret=%i\n",_ret_);
+ TRACE("Leave NtUserScrollWindowEx, ret=%lu\n",_ret_);
UserLeave();
END_CLEANUP;
}
{
PCURICON_OBJECT pIcon = NULL;
- if (!hIcon && pWnd)
+ if (hIcon)
{
- hIcon = pWnd->pcls->hIconSm; // FIXME: Windows does not do that
- if(!hIcon)
- hIcon = pWnd->pcls->hIcon;
+ pIcon = UserGetCurIconObject(hIcon);
+ }
+ else if (pWnd)
+ {
+ pIcon = NC_IconForWindow(pWnd);
+ // FIXME: NC_IconForWindow should reference it for us */
+ if (pIcon)
+ UserReferenceObject(pIcon);
}
-
- if (hIcon)
- pIcon = UserGetCurIconObject(hIcon);
if (pIcon)
{
LONG x = Rect.left - cx/2 + 1 + (Rect.bottom - Rect.top)/2; // this is really what Window does
LONG y = (Rect.top + Rect.bottom)/2 - cy/2; // center
UserDrawIconEx(hDc, x, y, pIcon, cx, cy, 0, NULL, DI_NORMAL);
+ UserDereferenceObject(pIcon);
+ }
+ else
+ {
+ HasIcon = FALSE;
}
}
- if (hIcon)
+ if (HasIcon)
Rect.left += Rect.bottom - Rect.top;
if((uFlags & DC_TEXT))
ERR("RealizePalette Desktop.");
hdc = UserGetWindowDC(pWnd);
IntPaintDesktop(hdc);
- UserReleaseDC(pWnd,hdc,FALSE);
+ UserReleaseDC(pWnd,hdc,FALSE);
}
UserSendNotifyMessage((HWND)HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hWnd, 0);
}
CONST RECT *lpUnsafeRect,
BOOL bErase)
{
- return NtUserRedrawWindow(hWnd, lpUnsafeRect, NULL, RDW_INVALIDATE | (bErase? RDW_ERASE : 0));
+ UINT flags = RDW_INVALIDATE | (bErase ? RDW_ERASE : 0);
+ if (!hWnd)
+ {
+ flags = RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW;
+ lpUnsafeRect = NULL;
+ }
+ return NtUserRedrawWindow(hWnd, lpUnsafeRect, NULL, flags);
}
BOOL
HRGN hRgn,
BOOL bErase)
{
+ if (!hWnd)
+ {
+ EngSetLastError( ERROR_INVALID_WINDOW_HANDLE );
+ return FALSE;
+ }
return NtUserRedrawWindow(hWnd, NULL, hRgn, RDW_INVALIDATE | (bErase? RDW_ERASE : 0));
}
HWND hWnd,
const RECT *lpRect)
{
- if (hWnd)
+ UINT flags = RDW_VALIDATE;
+ if (!hWnd)
{
- return NtUserRedrawWindow(hWnd, lpRect, NULL, RDW_VALIDATE );
+ flags = RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW;
+ lpRect = NULL;
}
- return NtUserRedrawWindow(hWnd, lpRect, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ERASENOW|RDW_ALLCHILDREN);
+ return NtUserRedrawWindow(hWnd, lpRect, NULL, flags);
}
/* EOF */