reactos/win32ss/user/ntuser/painting.c

2622 lines
64 KiB
C
Raw Permalink Normal View History

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Win32k subsystem
* PURPOSE: Window painting function
* FILE: win32ss/user/ntuser/painting.c
* PROGRAMER: Filip Navara (xnavara@volny.cz)
*/
#include <win32k.h>
DBG_DEFAULT_CHANNEL(UserPainting);
BOOL UserExtTextOutW(HDC hdc, INT x, INT y, UINT flags, PRECTL lprc,
LPCWSTR lpString, UINT count);
/* PRIVATE FUNCTIONS **********************************************************/
/**
* @name IntIntersectWithParents
*
* Intersect window rectangle with all parent client rectangles.
*
* @param Child
* Pointer to child window to start intersecting from.
* @param WindowRect
* Pointer to rectangle that we want to intersect in screen
* coordinates on input and intersected rectangle on output (if TRUE
* is returned).
*
* @return
* If any parent is minimized or invisible or the resulting rectangle
* is empty then FALSE is returned. Otherwise TRUE is returned.
*/
BOOL FASTCALL
IntIntersectWithParents(PWND Child, RECTL *WindowRect)
{
PWND ParentWnd;
if (Child->ExStyle & WS_EX_REDIRECTED)
return TRUE;
ParentWnd = Child->spwndParent;
while (ParentWnd != NULL)
{
if (!(ParentWnd->style & WS_VISIBLE) ||
(ParentWnd->style & WS_MINIMIZE) ||
!RECTL_bIntersectRect(WindowRect, WindowRect, &ParentWnd->rcClient) )
{
return FALSE;
}
if (ParentWnd->ExStyle & WS_EX_REDIRECTED)
return TRUE;
ParentWnd = ParentWnd->spwndParent;
}
return TRUE;
}
BOOL FASTCALL
IntValidateParents(PWND Child, BOOL Recurse)
{
RECTL ParentRect, Rect;
BOOL Start, Ret = TRUE;
PWND ParentWnd = Child;
PREGION Rgn = NULL;
if (ParentWnd->style & WS_CHILD)
{
do
ParentWnd = ParentWnd->spwndParent;
while (ParentWnd->style & WS_CHILD);
}
// No pending nonclient paints.
if (!(ParentWnd->state & WNDS_SYNCPAINTPENDING)) Recurse = FALSE;
Start = TRUE;
ParentWnd = Child->spwndParent;
while (ParentWnd)
{
if (ParentWnd->style & WS_CLIPCHILDREN)
break;
if (ParentWnd->hrgnUpdate != 0)
{
if (Recurse)
{
Ret = FALSE;
break;
}
// Start with child clipping.
if (Start)
{
Start = FALSE;
Rect = Child->rcWindow;
if (!IntIntersectWithParents(Child, &Rect)) break;
Rgn = IntSysCreateRectpRgnIndirect(&Rect);
if (Child->hrgnClip)
{
PREGION RgnClip = REGION_LockRgn(Child->hrgnClip);
IntGdiCombineRgn(Rgn, Rgn, RgnClip, RGN_AND);
REGION_UnlockRgn(RgnClip);
}
}
ParentRect = ParentWnd->rcWindow;
if (!IntIntersectWithParents(ParentWnd, &ParentRect)) break;
IntInvalidateWindows( ParentWnd,
Rgn,
RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOUPDATEDIRTY);
}
ParentWnd = ParentWnd->spwndParent;
}
if (Rgn) REGION_Delete(Rgn);
return Ret;
}
/*
Synchronize painting to the top-level windows of other threads.
*/
VOID FASTCALL
IntSendSyncPaint(PWND Wnd, ULONG Flags)
{
PTHREADINFO ptiCur, ptiWnd;
PUSER_SENT_MESSAGE Message;
PLIST_ENTRY Entry;
BOOL bSend = TRUE;
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.
*/
if ( Wnd->head.pti != ptiCur &&
Wnd->state & WNDS_SENDNCPAINT &&
Wnd->state & WNDS_SENDERASEBACKGROUND &&
Wnd->style & WS_VISIBLE)
{
// For testing, if you see this, break out the Champagne and have a party!
TRACE("SendSyncPaint Wnd in State!\n");
if (!IsListEmpty(&ptiWnd->SentMessagesListHead))
{
// Scan sent queue messages to see if we received sync paint messages.
Entry = ptiWnd->SentMessagesListHead.Flink;
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
do
{
ERR("LOOP it\n");
if (Message->Msg.message == WM_SYNCPAINT &&
Message->Msg.hwnd == UserHMGetHandle(Wnd))
{ // Already received so exit out.
ERR("SendSyncPaint Found one in the Sent Msg Queue!\n");
bSend = FALSE;
break;
}
Entry = Message->ListEntry.Flink;
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
}
while (Entry != &ptiWnd->SentMessagesListHead);
}
if (bSend)
{
TRACE("Sending WM_SYNCPAINT\n");
// This message has no parameters. But it does! Pass Flags along.
co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_SYNCPAINT, Flags, 0);
Wnd->state |= WNDS_SYNCPAINTPENDING;
}
}
// Send to all the children if this is the desktop window.
if (UserIsDesktopWindow(Wnd))
{
if ( Flags & RDW_ALLCHILDREN ||
( !(Flags & RDW_NOCHILDREN) && Wnd->style & WS_CLIPCHILDREN))
{
PWND spwndChild = Wnd->spwndChild;
while(spwndChild)
{
if ( spwndChild->style & WS_CHILD &&
spwndChild->head.pti != ptiCur)
{
spwndChild = spwndChild->spwndNext;
continue;
}
IntSendSyncPaint( spwndChild, Flags );
spwndChild = spwndChild->spwndNext;
}
}
}
}
/*
* @name IntCalcWindowRgn
*
* Get a window or client region.
*/
HRGN FASTCALL
IntCalcWindowRgn(PWND Wnd, BOOL Client)
{
HRGN hRgnWindow;
if (Client)
{
hRgnWindow = NtGdiCreateRectRgn(
Wnd->rcClient.left,
Wnd->rcClient.top,
Wnd->rcClient.right,
Wnd->rcClient.bottom);
}
else
{
hRgnWindow = NtGdiCreateRectRgn(
Wnd->rcWindow.left,
Wnd->rcWindow.top,
Wnd->rcWindow.right,
Wnd->rcWindow.bottom);
}
if (Wnd->hrgnClip != NULL && !(Wnd->style & WS_MINIMIZE))
{
NtGdiOffsetRgn(hRgnWindow,
-Wnd->rcWindow.left,
-Wnd->rcWindow.top);
NtGdiCombineRgn(hRgnWindow, hRgnWindow, Wnd->hrgnClip, RGN_AND);
NtGdiOffsetRgn(hRgnWindow,
Wnd->rcWindow.left,
Wnd->rcWindow.top);
}
return hRgnWindow;
}
/*
* @name IntGetNCUpdateRgn
*
* Get non-client update region of a window and optionally validate it.
*
* @param Window
* Pointer to window to get the NC update region from.
* @param Validate
* Set to TRUE to force validating the NC update region.
*
* @return
* Handle to NC update region. The caller is responsible for deleting
* it.
*/
HRGN FASTCALL
IntGetNCUpdateRgn(PWND Window, BOOL Validate)
{
HRGN hRgnNonClient;
HRGN hRgnWindow;
UINT RgnType, NcType;
RECT update;
if (Window->hrgnUpdate != NULL &&
Window->hrgnUpdate != HRGN_WINDOW)
{
hRgnNonClient = IntCalcWindowRgn(Window, FALSE);
/*
* If region creation fails it's safe to fallback to whole
* window region.
*/
if (hRgnNonClient == NULL)
{
return HRGN_WINDOW;
}
hRgnWindow = IntCalcWindowRgn(Window, TRUE);
if (hRgnWindow == NULL)
{
[WIN32K] Rewrite of the GDI handle manager - The old handle manager used a completely retarded spinlock in combination with KeDelayExecutionThread() for both exclusive and shared locks. This is probably the most uneffective algorithm possible. It was also duplicating code everywhere and it was a overall mess It is now replaced with a lock-free reference counter for shared locks and a pushlock for exclusive locks. -> Better performance and scalability. - Allocate user mode object attributes from the new gdi pool. This way, we don't need any caching, since the pool serves as a cache. Its also much faster and uses much less memory. - Allow object allocations of different size, instead of fixed size from a table. This way a single allocation can take care of actual needs. - Allow allcoating objects without a handle and insert them into the handle table later - Properly synchronize the process GDIHandleCount. Now gdiview and taskmanager show the correct number of gdi handles. - Implement a new event tracking system, that is capable of tracking all reverences and locks of objects and pool allocations to help track possible leaks - Make sure that all objects of a process are deleted in cleanup - Make sure all usermode memory allocations are freed, when cleaning up the process pool. - Make sure that each object type is using the correct type of lock (either shared or exclusive, not a mixture) - Fix some object / reference leaks - Lots of inferface improvements - Use global variables for certain things instead of members in the mapped gdi handle table - Make IntSysCreateRectpRgn create a region without a handle - Fix detection od source and mask use in GreStretchBltMask - Use GDIOBJ_bLockMultipleObjects in NtGdiCombineRegion to avoid possible deadlocks - Fix NtGdiAbortPath to reset DCPATH_ACTIVE flag in the dc and only bail out on error, instead of always - Replace DC_AllocateDcAttr and DC_AllocDcAttr with DC_bAllocDcAttr using the new user mode pool - Remove DCU_SyncDcAttrtoUser and DCU_SynchDcAttrtoUser. Those functions were unused and didn't do anything useful anyway, - Replace IntGdiSetDCOwnerEx and DC_SetOwnership with GreSetDCOwner, remove unused NoSetBrush parameter - Replace GDIOBJ_bValidateHandle and IsObjectDead with GreIsHandleValid - Chage GDIOBJ_bLockMultipleObjects: pass object type, return a BOOL, whether all objects could be locked, cleanup on failure svn path=/trunk/; revision=51470
2011-04-28 08:26:46 +00:00
GreDeleteObject(hRgnNonClient);
return HRGN_WINDOW;
}
NcType = IntGdiGetRgnBox(hRgnNonClient, &update);
RgnType = NtGdiCombineRgn(hRgnNonClient, hRgnNonClient, hRgnWindow, RGN_DIFF);
if (RgnType == ERROR)
{
[WIN32K] Rewrite of the GDI handle manager - The old handle manager used a completely retarded spinlock in combination with KeDelayExecutionThread() for both exclusive and shared locks. This is probably the most uneffective algorithm possible. It was also duplicating code everywhere and it was a overall mess It is now replaced with a lock-free reference counter for shared locks and a pushlock for exclusive locks. -> Better performance and scalability. - Allocate user mode object attributes from the new gdi pool. This way, we don't need any caching, since the pool serves as a cache. Its also much faster and uses much less memory. - Allow object allocations of different size, instead of fixed size from a table. This way a single allocation can take care of actual needs. - Allow allcoating objects without a handle and insert them into the handle table later - Properly synchronize the process GDIHandleCount. Now gdiview and taskmanager show the correct number of gdi handles. - Implement a new event tracking system, that is capable of tracking all reverences and locks of objects and pool allocations to help track possible leaks - Make sure that all objects of a process are deleted in cleanup - Make sure all usermode memory allocations are freed, when cleaning up the process pool. - Make sure that each object type is using the correct type of lock (either shared or exclusive, not a mixture) - Fix some object / reference leaks - Lots of inferface improvements - Use global variables for certain things instead of members in the mapped gdi handle table - Make IntSysCreateRectpRgn create a region without a handle - Fix detection od source and mask use in GreStretchBltMask - Use GDIOBJ_bLockMultipleObjects in NtGdiCombineRegion to avoid possible deadlocks - Fix NtGdiAbortPath to reset DCPATH_ACTIVE flag in the dc and only bail out on error, instead of always - Replace DC_AllocateDcAttr and DC_AllocDcAttr with DC_bAllocDcAttr using the new user mode pool - Remove DCU_SyncDcAttrtoUser and DCU_SynchDcAttrtoUser. Those functions were unused and didn't do anything useful anyway, - Replace IntGdiSetDCOwnerEx and DC_SetOwnership with GreSetDCOwner, remove unused NoSetBrush parameter - Replace GDIOBJ_bValidateHandle and IsObjectDead with GreIsHandleValid - Chage GDIOBJ_bLockMultipleObjects: pass object type, return a BOOL, whether all objects could be locked, cleanup on failure svn path=/trunk/; revision=51470
2011-04-28 08:26:46 +00:00
GreDeleteObject(hRgnWindow);
GreDeleteObject(hRgnNonClient);
return HRGN_WINDOW;
}
else if (RgnType == NULLREGION)
{
[WIN32K] Rewrite of the GDI handle manager - The old handle manager used a completely retarded spinlock in combination with KeDelayExecutionThread() for both exclusive and shared locks. This is probably the most uneffective algorithm possible. It was also duplicating code everywhere and it was a overall mess It is now replaced with a lock-free reference counter for shared locks and a pushlock for exclusive locks. -> Better performance and scalability. - Allocate user mode object attributes from the new gdi pool. This way, we don't need any caching, since the pool serves as a cache. Its also much faster and uses much less memory. - Allow object allocations of different size, instead of fixed size from a table. This way a single allocation can take care of actual needs. - Allow allcoating objects without a handle and insert them into the handle table later - Properly synchronize the process GDIHandleCount. Now gdiview and taskmanager show the correct number of gdi handles. - Implement a new event tracking system, that is capable of tracking all reverences and locks of objects and pool allocations to help track possible leaks - Make sure that all objects of a process are deleted in cleanup - Make sure all usermode memory allocations are freed, when cleaning up the process pool. - Make sure that each object type is using the correct type of lock (either shared or exclusive, not a mixture) - Fix some object / reference leaks - Lots of inferface improvements - Use global variables for certain things instead of members in the mapped gdi handle table - Make IntSysCreateRectpRgn create a region without a handle - Fix detection od source and mask use in GreStretchBltMask - Use GDIOBJ_bLockMultipleObjects in NtGdiCombineRegion to avoid possible deadlocks - Fix NtGdiAbortPath to reset DCPATH_ACTIVE flag in the dc and only bail out on error, instead of always - Replace DC_AllocateDcAttr and DC_AllocDcAttr with DC_bAllocDcAttr using the new user mode pool - Remove DCU_SyncDcAttrtoUser and DCU_SynchDcAttrtoUser. Those functions were unused and didn't do anything useful anyway, - Replace IntGdiSetDCOwnerEx and DC_SetOwnership with GreSetDCOwner, remove unused NoSetBrush parameter - Replace GDIOBJ_bValidateHandle and IsObjectDead with GreIsHandleValid - Chage GDIOBJ_bLockMultipleObjects: pass object type, return a BOOL, whether all objects could be locked, cleanup on failure svn path=/trunk/; revision=51470
2011-04-28 08:26:46 +00:00
GreDeleteObject(hRgnWindow);
GreDeleteObject(hRgnNonClient);
Window->state &= ~WNDS_UPDATEDIRTY;
return NULL;
}
/*
* Remove the nonclient region from the standard update region if
* we were asked for it.
*/
if (Validate)
{
if (NtGdiCombineRgn(Window->hrgnUpdate, Window->hrgnUpdate, hRgnWindow, RGN_AND) == NULLREGION)
{
IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
[WIN32K] Rewrite of the GDI handle manager - The old handle manager used a completely retarded spinlock in combination with KeDelayExecutionThread() for both exclusive and shared locks. This is probably the most uneffective algorithm possible. It was also duplicating code everywhere and it was a overall mess It is now replaced with a lock-free reference counter for shared locks and a pushlock for exclusive locks. -> Better performance and scalability. - Allocate user mode object attributes from the new gdi pool. This way, we don't need any caching, since the pool serves as a cache. Its also much faster and uses much less memory. - Allow object allocations of different size, instead of fixed size from a table. This way a single allocation can take care of actual needs. - Allow allcoating objects without a handle and insert them into the handle table later - Properly synchronize the process GDIHandleCount. Now gdiview and taskmanager show the correct number of gdi handles. - Implement a new event tracking system, that is capable of tracking all reverences and locks of objects and pool allocations to help track possible leaks - Make sure that all objects of a process are deleted in cleanup - Make sure all usermode memory allocations are freed, when cleaning up the process pool. - Make sure that each object type is using the correct type of lock (either shared or exclusive, not a mixture) - Fix some object / reference leaks - Lots of inferface improvements - Use global variables for certain things instead of members in the mapped gdi handle table - Make IntSysCreateRectpRgn create a region without a handle - Fix detection od source and mask use in GreStretchBltMask - Use GDIOBJ_bLockMultipleObjects in NtGdiCombineRegion to avoid possible deadlocks - Fix NtGdiAbortPath to reset DCPATH_ACTIVE flag in the dc and only bail out on error, instead of always - Replace DC_AllocateDcAttr and DC_AllocDcAttr with DC_bAllocDcAttr using the new user mode pool - Remove DCU_SyncDcAttrtoUser and DCU_SynchDcAttrtoUser. Those functions were unused and didn't do anything useful anyway, - Replace IntGdiSetDCOwnerEx and DC_SetOwnership with GreSetDCOwner, remove unused NoSetBrush parameter - Replace GDIOBJ_bValidateHandle and IsObjectDead with GreIsHandleValid - Chage GDIOBJ_bLockMultipleObjects: pass object type, return a BOOL, whether all objects could be locked, cleanup on failure svn path=/trunk/; revision=51470
2011-04-28 08:26:46 +00:00
GreDeleteObject(Window->hrgnUpdate);
Window->state &= ~WNDS_UPDATEDIRTY;
Window->hrgnUpdate = NULL;
if (!(Window->state & WNDS_INTERNALPAINT))
MsqDecPaintCountQueue(Window->head.pti);
}
}
/* check if update rgn contains complete nonclient area */
if (NcType == SIMPLEREGION)
{
RECT window;
IntGetWindowRect( Window, &window );
if (IntEqualRect( &window, &update ))
{
GreDeleteObject(hRgnNonClient);
hRgnNonClient = HRGN_WINDOW;
}
}
[WIN32K] Rewrite of the GDI handle manager - The old handle manager used a completely retarded spinlock in combination with KeDelayExecutionThread() for both exclusive and shared locks. This is probably the most uneffective algorithm possible. It was also duplicating code everywhere and it was a overall mess It is now replaced with a lock-free reference counter for shared locks and a pushlock for exclusive locks. -> Better performance and scalability. - Allocate user mode object attributes from the new gdi pool. This way, we don't need any caching, since the pool serves as a cache. Its also much faster and uses much less memory. - Allow object allocations of different size, instead of fixed size from a table. This way a single allocation can take care of actual needs. - Allow allcoating objects without a handle and insert them into the handle table later - Properly synchronize the process GDIHandleCount. Now gdiview and taskmanager show the correct number of gdi handles. - Implement a new event tracking system, that is capable of tracking all reverences and locks of objects and pool allocations to help track possible leaks - Make sure that all objects of a process are deleted in cleanup - Make sure all usermode memory allocations are freed, when cleaning up the process pool. - Make sure that each object type is using the correct type of lock (either shared or exclusive, not a mixture) - Fix some object / reference leaks - Lots of inferface improvements - Use global variables for certain things instead of members in the mapped gdi handle table - Make IntSysCreateRectpRgn create a region without a handle - Fix detection od source and mask use in GreStretchBltMask - Use GDIOBJ_bLockMultipleObjects in NtGdiCombineRegion to avoid possible deadlocks - Fix NtGdiAbortPath to reset DCPATH_ACTIVE flag in the dc and only bail out on error, instead of always - Replace DC_AllocateDcAttr and DC_AllocDcAttr with DC_bAllocDcAttr using the new user mode pool - Remove DCU_SyncDcAttrtoUser and DCU_SynchDcAttrtoUser. Those functions were unused and didn't do anything useful anyway, - Replace IntGdiSetDCOwnerEx and DC_SetOwnership with GreSetDCOwner, remove unused NoSetBrush parameter - Replace GDIOBJ_bValidateHandle and IsObjectDead with GreIsHandleValid - Chage GDIOBJ_bLockMultipleObjects: pass object type, return a BOOL, whether all objects could be locked, cleanup on failure svn path=/trunk/; revision=51470
2011-04-28 08:26:46 +00:00
GreDeleteObject(hRgnWindow);
return hRgnNonClient;
}
else
{
return Window->hrgnUpdate;
}
}
VOID FASTCALL
IntSendNCPaint(PWND pWnd, HRGN hRgn)
{
pWnd->state &= ~WNDS_SENDNCPAINT;
if ( pWnd == GetW32ThreadInfo()->MessageQueue->spwndActive &&
!(pWnd->state & WNDS_ACTIVEFRAME))
{
pWnd->state |= WNDS_ACTIVEFRAME;
pWnd->state &= ~WNDS_NONCPAINT;
hRgn = HRGN_WINDOW;
}
if (pWnd->state2 & WNDS2_FORCEFULLNCPAINTCLIPRGN)
{
pWnd->state2 &= ~WNDS2_FORCEFULLNCPAINTCLIPRGN;
hRgn = HRGN_WINDOW;
}
if (hRgn) co_IntSendMessage(UserHMGetHandle(pWnd), WM_NCPAINT, (WPARAM)hRgn, 0);
}
VOID FASTCALL
IntSendChildNCPaint(PWND pWnd)
{
pWnd = pWnd->spwndChild;
while (pWnd)
{
if ((pWnd->hrgnUpdate == NULL) && (pWnd->state & WNDS_SENDNCPAINT))
{
PWND Next;
USER_REFERENCE_ENTRY Ref;
/* Reference, IntSendNCPaint leaves win32k */
UserRefObjectCo(pWnd, &Ref);
IntSendNCPaint(pWnd, HRGN_WINDOW);
/* Make sure to grab next one before dereferencing/freeing */
Next = pWnd->spwndNext;
UserDerefObjectCo(pWnd);
pWnd = Next;
}
else
{
pWnd = pWnd->spwndNext;
}
}
}
/*
* IntPaintWindows
*
* Internal function used by IntRedrawWindow.
*/
VOID FASTCALL
co_IntPaintWindows(PWND Wnd, ULONG Flags, BOOL Recurse)
{
HDC hDC;
HWND hWnd = UserHMGetHandle(Wnd);
HRGN TempRegion = NULL;
Wnd->state &= ~WNDS_PAINTNOTPROCESSED;
if (Wnd->state & WNDS_SENDNCPAINT ||
Wnd->state & WNDS_SENDERASEBACKGROUND)
{
if (!(Wnd->style & WS_VISIBLE))
{
Wnd->state &= ~(WNDS_SENDNCPAINT|WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
return;
}
else
{
if (Wnd->hrgnUpdate == NULL)
{
Wnd->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
}
if (Wnd->head.pti == PsGetCurrentThreadWin32Thread())
{
if (Wnd->state & WNDS_SENDNCPAINT)
{
TempRegion = IntGetNCUpdateRgn(Wnd, TRUE);
IntSendNCPaint(Wnd, TempRegion);
if (TempRegion > HRGN_WINDOW && GreIsHandleValid(TempRegion))
{
/* NOTE: The region can already be deleted! */
GreDeleteObject(TempRegion);
}
}
if (Wnd->state & WNDS_SENDERASEBACKGROUND)
{
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
if (Wnd->hrgnUpdate)
{
hDC = UserGetDCEx( Wnd,
Wnd->hrgnUpdate,
DCX_CACHE|DCX_USESTYLE|DCX_INTERSECTRGN|DCX_KEEPCLIPRGN);
if (Wnd->head.pti->ppi != pti->ppi)
{
ERR("Sending DC to another Process!!!\n");
}
Wnd->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
// Kill the loop, so Clear before we send.
if (!co_IntSendMessage(hWnd, WM_ERASEBKGND, (WPARAM)hDC, 0))
{
Wnd->state |= (WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
}
UserReleaseDC(Wnd, hDC, FALSE);
}
}
}
}
}
/*
* Check that the window is still valid at this point
*/
if (!IntIsWindow(hWnd))
{
return;
}
/*
* Paint child windows.
*/
if (!(Flags & RDW_NOCHILDREN) &&
!(Wnd->style & WS_MINIMIZE) &&
( Flags & RDW_ALLCHILDREN ||
(Flags & RDW_CLIPCHILDREN && Wnd->style & WS_CLIPCHILDREN) ) )
{
HWND *List, *phWnd;
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
if ((List = IntWinListChildren(Wnd)))
{
for (phWnd = List; *phWnd; ++phWnd)
{
if ((Wnd = UserGetWindowObject(*phWnd)) == NULL)
continue;
if (Wnd->head.pti != pti && Wnd->style & WS_CHILD)
continue;
if (Wnd->style & WS_VISIBLE)
{
USER_REFERENCE_ENTRY Ref;
UserRefObjectCo(Wnd, &Ref);
co_IntPaintWindows(Wnd, Flags, TRUE);
UserDerefObjectCo(Wnd);
}
}
ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
}
}
}
/*
* IntUpdateWindows
*
* Internal function used by IntRedrawWindow, simplecall.
*/
VOID FASTCALL
co_IntUpdateWindows(PWND Wnd, ULONG Flags, BOOL Recurse)
{
HWND hWnd = UserHMGetHandle(Wnd);
if ( Wnd->hrgnUpdate != NULL || Wnd->state & WNDS_INTERNALPAINT )
{
if (Wnd->hrgnUpdate)
{
if (!IntValidateParents(Wnd, Recurse))
{
return;
}
}
if (Wnd->state & WNDS_INTERNALPAINT)
{
Wnd->state &= ~WNDS_INTERNALPAINT;
if (Wnd->hrgnUpdate == NULL)
MsqDecPaintCountQueue(Wnd->head.pti);
}
Wnd->state |= WNDS_PAINTNOTPROCESSED;
Wnd->state &= ~WNDS_UPDATEDIRTY;
Wnd->state2 |= WNDS2_WMPAINTSENT;
co_IntSendMessage(hWnd, WM_PAINT, 0, 0);
if (Wnd->state & WNDS_PAINTNOTPROCESSED)
{
USER_REFERENCE_ENTRY Ref;
UserRefObjectCo(Wnd, &Ref);
co_IntPaintWindows(Wnd, RDW_NOCHILDREN, FALSE);
UserDerefObjectCo(Wnd);
}
}
// Force flags as a toggle. Fixes msg:test_paint_messages:WmChildPaintNc.
Flags = (Flags & RDW_NOCHILDREN) ? RDW_NOCHILDREN : RDW_ALLCHILDREN; // All children is the default.
/*
* Update child windows.
*/
if (!(Flags & RDW_NOCHILDREN) &&
(Flags & RDW_ALLCHILDREN) &&
!UserIsDesktopWindow(Wnd))
{
PWND Child;
for (Child = Wnd->spwndChild; Child; Child = Child->spwndNext)
{
/* transparent window, check for non-transparent sibling to paint first, then skip it */
if ( Child->ExStyle & WS_EX_TRANSPARENT &&
( Child->hrgnUpdate != NULL || Child->state & WNDS_INTERNALPAINT ) )
{
PWND Next = Child->spwndNext;
while (Next)
{
if ( Next->hrgnUpdate != NULL || Next->state & WNDS_INTERNALPAINT ) break;
Next = Next->spwndNext;
}
if (Next) continue;
}
if (Child->style & WS_VISIBLE)
{
USER_REFERENCE_ENTRY Ref;
UserRefObjectCo(Child, &Ref);
co_IntUpdateWindows(Child, Flags, TRUE);
UserDerefObjectCo(Child);
}
}
}
}
VOID FASTCALL
UserUpdateWindows(PWND pWnd, ULONG Flags)
{
// If transparent and any sibling windows below needs to be painted, leave.
if (pWnd->ExStyle & WS_EX_TRANSPARENT)
{
PWND Next = pWnd->spwndNext;
while(Next)
{
if ( Next->head.pti == pWnd->head.pti &&
( Next->hrgnUpdate != NULL || Next->state & WNDS_INTERNALPAINT) )
{
return;
}
Next = Next->spwndNext;
}
}
co_IntUpdateWindows(pWnd, Flags, FALSE);
}
VOID FASTCALL
UserSyncAndPaintWindows(PWND pWnd, ULONG Flags)
{
PWND Parent = pWnd;
// Find parent, if it needs to be painted, leave.
while(TRUE)
{
if ((Parent = Parent->spwndParent) == NULL) break;
if ( Parent->style & WS_CLIPCHILDREN ) break;
if ( Parent->hrgnUpdate != NULL || Parent->state & WNDS_INTERNALPAINT ) return;
}
IntSendSyncPaint(pWnd, Flags);
co_IntPaintWindows(pWnd, Flags, FALSE);
}
/*
* IntInvalidateWindows
*
* Internal function used by IntRedrawWindow, UserRedrawDesktop,
* co_WinPosSetWindowPos, co_UserRedrawWindow.
*/
VOID FASTCALL
IntInvalidateWindows(PWND Wnd, PREGION Rgn, ULONG Flags)
{
INT RgnType = NULLREGION;
BOOL HadPaintMessage;
TRACE("IntInvalidateWindows start Rgn %p\n",Rgn);
if ( Rgn > PRGN_WINDOW )
{
/*
* If the nonclient is not to be redrawn, clip the region to the client
* rect
*/
if ((Flags & RDW_INVALIDATE) != 0 && (Flags & RDW_FRAME) == 0)
{
PREGION RgnClient;
RgnClient = IntSysCreateRectpRgnIndirect(&Wnd->rcClient);
if (RgnClient)
{
RgnType = IntGdiCombineRgn(Rgn, Rgn, RgnClient, RGN_AND);
REGION_Delete(RgnClient);
}
}
/*
* Clip the given region with window rectangle (or region)
*/
if (!Wnd->hrgnClip || (Wnd->style & WS_MINIMIZE))
{
PREGION RgnWindow = IntSysCreateRectpRgnIndirect(&Wnd->rcWindow);
if (RgnWindow)
{
RgnType = IntGdiCombineRgn(Rgn, Rgn, RgnWindow, RGN_AND);
REGION_Delete(RgnWindow);
}
}
else
{
PREGION RgnClip = REGION_LockRgn(Wnd->hrgnClip);
if (RgnClip)
{
REGION_bOffsetRgn(Rgn,
-Wnd->rcWindow.left,
-Wnd->rcWindow.top);
RgnType = IntGdiCombineRgn(Rgn, Rgn, RgnClip, RGN_AND);
REGION_bOffsetRgn(Rgn,
Wnd->rcWindow.left,
Wnd->rcWindow.top);
REGION_UnlockRgn(RgnClip);
}
}
}
else
{
RgnType = NULLREGION;
}
/* Nothing to paint, just return */
if ((RgnType == NULLREGION && (Flags & RDW_INVALIDATE)) || RgnType == ERROR)
{
return;
}
/*
* Save current state of pending updates
*/
HadPaintMessage = IntIsWindowDirty(Wnd);
/*
* Update the region and flags
*/
// The following flags are used to invalidate the window.
if (Flags & (RDW_INVALIDATE|RDW_INTERNALPAINT|RDW_ERASE|RDW_FRAME))
{
if (Flags & RDW_INTERNALPAINT)
{
Wnd->state |= WNDS_INTERNALPAINT;
}
if (Flags & RDW_INVALIDATE )
{
PREGION RgnUpdate;
Wnd->state &= ~WNDS_NONCPAINT;
/* If not the same thread set it dirty. */
if (Wnd->head.pti != PsGetCurrentThreadWin32Thread())
{
Wnd->state |= WNDS_UPDATEDIRTY;
if (Wnd->state2 & WNDS2_WMPAINTSENT)
Wnd->state2 |= WNDS2_ENDPAINTINVALIDATE;
}
if (Flags & RDW_FRAME)
Wnd->state |= WNDS_SENDNCPAINT;
if (Flags & RDW_ERASE)
Wnd->state |= WNDS_SENDERASEBACKGROUND;
if (RgnType != NULLREGION && Rgn > PRGN_WINDOW)
{
if (Wnd->hrgnUpdate == NULL)
{
Wnd->hrgnUpdate = NtGdiCreateRectRgn(0, 0, 0, 0);
IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_PUBLIC);
}
if (Wnd->hrgnUpdate != HRGN_WINDOW)
{
RgnUpdate = REGION_LockRgn(Wnd->hrgnUpdate);
if (RgnUpdate)
{
RgnType = IntGdiCombineRgn(RgnUpdate, RgnUpdate, Rgn, RGN_OR);
REGION_UnlockRgn(RgnUpdate);
if (RgnType == NULLREGION)
{
IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(Wnd->hrgnUpdate);
Wnd->hrgnUpdate = NULL;
}
}
}
}
Flags |= RDW_ERASE|RDW_FRAME; // For children.
}
if (!HadPaintMessage && IntIsWindowDirty(Wnd))
{
MsqIncPaintCountQueue(Wnd->head.pti);
}
} // The following flags are used to validate the window.
else if (Flags & (RDW_VALIDATE|RDW_NOINTERNALPAINT|RDW_NOERASE|RDW_NOFRAME))
{
if (Wnd->state & WNDS_UPDATEDIRTY && !(Flags & RDW_NOUPDATEDIRTY))
return;
if (Flags & RDW_NOINTERNALPAINT)
{
Wnd->state &= ~WNDS_INTERNALPAINT;
}
if (Flags & RDW_VALIDATE)
{
if (Flags & RDW_NOFRAME)
Wnd->state &= ~WNDS_SENDNCPAINT;
if (Flags & RDW_NOERASE)
Wnd->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
if (Wnd->hrgnUpdate > HRGN_WINDOW && RgnType != NULLREGION && Rgn > PRGN_WINDOW)
{
PREGION RgnUpdate = REGION_LockRgn(Wnd->hrgnUpdate);
if (RgnUpdate)
{
RgnType = IntGdiCombineRgn(RgnUpdate, RgnUpdate, Rgn, RGN_DIFF);
REGION_UnlockRgn(RgnUpdate);
if (RgnType == NULLREGION)
{
IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(Wnd->hrgnUpdate);
Wnd->hrgnUpdate = NULL;
}
}
}
// If update is null, do not erase.
if (Wnd->hrgnUpdate == NULL)
{
Wnd->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
}
}
if (HadPaintMessage && !IntIsWindowDirty(Wnd))
{
MsqDecPaintCountQueue(Wnd->head.pti);
}
}
/*
* Process children if needed
*/
if (!(Flags & RDW_NOCHILDREN) &&
!(Wnd->style & WS_MINIMIZE) &&
((Flags & RDW_ALLCHILDREN) || !(Wnd->style & WS_CLIPCHILDREN)))
{
PWND Child;
for (Child = Wnd->spwndChild; Child; Child = Child->spwndNext)
{
if (Child->style & WS_VISIBLE)
{
/*
* Recursive call to update children hrgnUpdate
*/
PREGION RgnTemp = IntSysCreateRectpRgn(0, 0, 0, 0);
if (RgnTemp)
{
if (Rgn > PRGN_WINDOW) IntGdiCombineRgn(RgnTemp, Rgn, 0, RGN_COPY);
IntInvalidateWindows(Child, ((Rgn > PRGN_WINDOW)?RgnTemp:Rgn), Flags);
REGION_Delete(RgnTemp);
}
}
}
}
TRACE("IntInvalidateWindows exit\n");
}
/*
* IntIsWindowDrawable
*
* Remarks
* Window is drawable when it is visible and all parents are not
* minimized.
*/
BOOL FASTCALL
IntIsWindowDrawable(PWND Wnd)
{
PWND WndObject;
for (WndObject = Wnd; WndObject != NULL; WndObject = WndObject->spwndParent)
{
if ( WndObject->state2 & WNDS2_INDESTROY ||
WndObject->state & WNDS_DESTROYED ||
!WndObject ||
!(WndObject->style & WS_VISIBLE) ||
((WndObject->style & WS_MINIMIZE) && (WndObject != Wnd)))
{
return FALSE;
}
}
return TRUE;
}
/*
* IntRedrawWindow
*
* Internal version of NtUserRedrawWindow that takes WND as
* first parameter.
*/
BOOL FASTCALL
co_UserRedrawWindow(
PWND Window,
const RECTL* UpdateRect,
PREGION UpdateRgn,
ULONG Flags)
{
PREGION TmpRgn = NULL;
TRACE("co_UserRedrawWindow start Rgn %p\n",UpdateRgn);
/*
* Step 1.
* Validation of passed parameters.
*/
if (!IntIsWindowDrawable(Window))
{
return TRUE; // Just do nothing!!!
}
if (Window == NULL)
{
Window = UserGetDesktopWindow();
}
/*
* Step 2.
* Transform the parameters UpdateRgn and UpdateRect into
* a region hRgn specified in screen coordinates.
*/
if (Flags & (RDW_INVALIDATE | RDW_VALIDATE)) // Both are OKAY!
{
/* We can't hold lock on GDI objects while doing roundtrips to user mode,
* so use a copy instead */
if (UpdateRgn)
{
TmpRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
if (UpdateRgn > PRGN_WINDOW)
{
IntGdiCombineRgn(TmpRgn, UpdateRgn, NULL, RGN_COPY);
}
if (Window != UserGetDesktopWindow())
{
REGION_bOffsetRgn(TmpRgn, Window->rcClient.left, Window->rcClient.top);
}
}
else
{
if (UpdateRect != NULL)
{
if (Window == UserGetDesktopWindow())
{
TmpRgn = IntSysCreateRectpRgnIndirect(UpdateRect);
}
else
{
TmpRgn = IntSysCreateRectpRgn(Window->rcClient.left + UpdateRect->left,
Window->rcClient.top + UpdateRect->top,
Window->rcClient.left + UpdateRect->right,
Window->rcClient.top + UpdateRect->bottom);
}
}
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))
TmpRgn = IntSysCreateRectpRgnIndirect(&Window->rcWindow);
}
else
{
if (!RECTL_bIsEmptyRect(&Window->rcClient))
TmpRgn = IntSysCreateRectpRgnIndirect(&Window->rcClient);
}
}
}
}
/* Fixes test RDW_INTERNALPAINT behavior */
if (TmpRgn == NULL)
{
TmpRgn = PRGN_WINDOW; // Need a region so the bits can be set!!!
}
/*
* Step 3.
* Adjust the window update region depending on hRgn and flags.
*/
if (Flags & (RDW_INVALIDATE | RDW_VALIDATE | RDW_INTERNALPAINT | RDW_NOINTERNALPAINT) &&
TmpRgn != NULL)
{
IntInvalidateWindows(Window, TmpRgn, Flags);
}
/*
* Step 4.
* Repaint and erase windows if needed.
*/
if (Flags & RDW_UPDATENOW)
{
UserUpdateWindows(Window, Flags);
}
else if (Flags & RDW_ERASENOW)
{
if ((Flags & (RDW_NOCHILDREN|RDW_ALLCHILDREN)) == 0)
Flags |= RDW_CLIPCHILDREN;
UserSyncAndPaintWindows(Window, Flags);
}
/*
* Step 5.
* Cleanup ;-)
*/
if (TmpRgn > PRGN_WINDOW)
{
REGION_Delete(TmpRgn);
}
TRACE("co_UserRedrawWindow exit\n");
return TRUE;
}
VOID FASTCALL
PaintSuspendedWindow(PWND pwnd, HRGN hrgnOrig)
{
if (pwnd->hrgnUpdate)
{
HDC hDC;
INT Flags = DC_NC|DC_NOSENDMSG;
HRGN hrgnTemp;
RECT Rect;
INT type;
PREGION prgn;
if (pwnd->hrgnUpdate > HRGN_WINDOW)
{
hrgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
type = NtGdiCombineRgn( hrgnTemp, pwnd->hrgnUpdate, 0, RGN_COPY);
if (type == ERROR)
{
GreDeleteObject(hrgnTemp);
hrgnTemp = HRGN_WINDOW;
}
}
else
{
hrgnTemp = GreCreateRectRgnIndirect(&pwnd->rcWindow);
}
if ( hrgnOrig &&
hrgnTemp > HRGN_WINDOW &&
NtGdiCombineRgn(hrgnTemp, hrgnTemp, hrgnOrig, RGN_AND) == NULLREGION)
{
GreDeleteObject(hrgnTemp);
return;
}
hDC = UserGetDCEx(pwnd, hrgnTemp, DCX_WINDOW|DCX_INTERSECTRGN|DCX_USESTYLE|DCX_KEEPCLIPRGN);
Rect = pwnd->rcWindow;
RECTL_vOffsetRect(&Rect, -pwnd->rcWindow.left, -pwnd->rcWindow.top);
// Clear out client area!
FillRect(hDC, &Rect, IntGetSysColorBrush(COLOR_WINDOW));
NC_DoNCPaint(pwnd, hDC, Flags); // Redraw without MENUs.
UserReleaseDC(pwnd, hDC, FALSE);
prgn = REGION_LockRgn(hrgnTemp);
IntInvalidateWindows(pwnd, prgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ALLCHILDREN);
REGION_UnlockRgn(prgn);
// Set updates for this window.
pwnd->state |= WNDS_SENDNCPAINT|WNDS_SENDERASEBACKGROUND|WNDS_UPDATEDIRTY;
// DCX_KEEPCLIPRGN is set. Check it anyway.
if (hrgnTemp > HRGN_WINDOW && GreIsHandleValid(hrgnTemp)) GreDeleteObject(hrgnTemp);
}
}
VOID FASTCALL
UpdateTheadChildren(PWND pWnd, HRGN hRgn)
{
PaintSuspendedWindow( pWnd, hRgn );
if (!(pWnd->style & WS_CLIPCHILDREN))
return;
pWnd = pWnd->spwndChild; // invalidate children if any.
while (pWnd)
{
UpdateTheadChildren( pWnd, hRgn );
pWnd = pWnd->spwndNext;
}
}
VOID FASTCALL
UpdateThreadWindows(PWND pWnd, PTHREADINFO pti, HRGN hRgn)
{
PWND pwndTemp;
for ( pwndTemp = pWnd;
pwndTemp;
pwndTemp = pwndTemp->spwndNext )
{
if (pwndTemp->head.pti == pti)
{
UserUpdateWindows(pwndTemp, RDW_ALLCHILDREN);
}
else
{
[WIN32SS:USER] Some minimal work and fixes concerning message queues timeouts. CORE-15147 - Rename CLIENTTHREADINFO::tickLastMsgChecked into timeLastRead as documented in https://reactos.org/wiki/Techwiki:Win32k/CLIENTTHREADINFO . This is the last time the message queue was read. - This is the structure member one must compare against the current tick count timestamp in order to heuristically determine whether a message queue thread is hung!! Fix MsqIsHung() in accordance, add extra debug logging in order to help us determining which of our code present regular GUI hangs, and add as well an extra "TimeOut" parameter so as not to hardcode a fixed value within that function but instead allowing its caller to specify possible different values. - THREADINFO::timeLast is on the contrary the last message time stamp, and will definitively differ from CLIENTTHREADINFO::timeLastRead . It should only be used for information purposes! - Accordingly, in NtUserGetThreadState()::THREADSTATE_UPTIMELASTREAD and in InitThreadCallback(), only (re-)initialize the timeLastRead member of the CLIENTTHREADINFO structure of the THREADINFO of interest. - In co_IntPeekMessage(), update more often the timeLastRead timestamp whenever the current message queue has been read (but NOT timeLast!! That one will be updated ONLY WHEN a message is found!). - In co_IntSendMessageTimeoutSingle() first check whether the window to which we send the message is being destroyed, before checking for queue hangs etc. Collapse the logic checks for queue hang and increase the hang timeout check to 4 times MSQ_HUNG (== 4 * 5 seconds) and display a debug trace.
2019-12-29 14:10:19 +00:00
if (IsThreadSuspended(pwndTemp->head.pti) || MsqIsHung(pwndTemp->head.pti, MSQ_HUNG))
{
UpdateTheadChildren(pwndTemp, hRgn);
}
else
UserUpdateWindows(pwndTemp, RDW_ALLCHILDREN);
}
}
}
BOOL FASTCALL
IntIsWindowDirty(PWND Wnd)
{
return ( Wnd->style & WS_VISIBLE &&
( Wnd->hrgnUpdate != NULL ||
Wnd->state & WNDS_INTERNALPAINT ) );
}
/*
Conditions to paint any window:
1. Update region is not null.
2. Internal paint flag is set.
3. Paint count is not zero.
*/
PWND FASTCALL
IntFindWindowToRepaint(PWND Window, PTHREADINFO Thread)
{
PWND hChild;
PWND TempWindow;
for (; Window != NULL; Window = Window->spwndNext)
{
if (IntWndBelongsToThread(Window, Thread))
{
if (IntIsWindowDirty(Window))
{
/* Make sure all non-transparent siblings are already drawn. */
if (Window->ExStyle & WS_EX_TRANSPARENT)
{
for (TempWindow = Window->spwndNext; TempWindow != NULL;
TempWindow = TempWindow->spwndNext)
{
if (!(TempWindow->ExStyle & WS_EX_TRANSPARENT) &&
IntWndBelongsToThread(TempWindow, Thread) &&
IntIsWindowDirty(TempWindow))
{
return TempWindow;
}
}
}
return Window;
}
}
/* find a child of the specified window that needs repainting */
if (Window->spwndChild)
{
hChild = IntFindWindowToRepaint(Window->spwndChild, Thread);
if (hChild != NULL)
return hChild;
}
}
return Window;
}
//
// Internal painting of windows.
//
VOID FASTCALL
IntPaintWindow( PWND Window )
{
// Handle normal painting.
co_IntPaintWindows( Window, RDW_NOCHILDREN, FALSE );
}
BOOL FASTCALL
IntGetPaintMessage(
PWND Window,
UINT MsgFilterMin,
UINT MsgFilterMax,
PTHREADINFO Thread,
MSG *Message,
BOOL Remove)
{
PWND PaintWnd, StartWnd;
if ((MsgFilterMin != 0 || MsgFilterMax != 0) &&
(MsgFilterMin > WM_PAINT || MsgFilterMax < WM_PAINT))
return FALSE;
if (Thread->TIF_flags & TIF_SYSTEMTHREAD )
{
ERR("WM_PAINT is in a System Thread!\n");
}
StartWnd = UserGetDesktopWindow();
PaintWnd = IntFindWindowToRepaint(StartWnd, Thread);
Message->hwnd = PaintWnd ? UserHMGetHandle(PaintWnd) : NULL;
if (Message->hwnd == NULL && Thread->cPaintsReady)
{
// Find note in window.c:"PAINTING BUG".
ERR("WARNING SOMETHING HAS GONE WRONG: Thread marked as containing dirty windows, but no dirty windows found! Counts %u\n",Thread->cPaintsReady);
/* Hack to stop spamming the debug log ! */
Thread->cPaintsReady = 0;
return FALSE;
}
if (Message->hwnd == NULL)
return FALSE;
if (!(Window == NULL ||
PaintWnd == Window ||
IntIsChildWindow(Window, PaintWnd))) /* check that it is a child of the specified parent */
return FALSE;
if (PaintWnd->state & WNDS_INTERNALPAINT)
{
PaintWnd->state &= ~WNDS_INTERNALPAINT;
if (!PaintWnd->hrgnUpdate)
MsqDecPaintCountQueue(Thread);
}
PaintWnd->state2 &= ~WNDS2_STARTPAINT;
PaintWnd->state &= ~WNDS_UPDATEDIRTY;
Window = PaintWnd;
while (Window && !UserIsDesktopWindow(Window))
{
// Role back and check for clip children, do not set if any.
if (Window->spwndParent && !(Window->spwndParent->style & WS_CLIPCHILDREN))
{
PaintWnd->state2 |= WNDS2_WMPAINTSENT;
}
Window = Window->spwndParent;
}
Message->wParam = Message->lParam = 0;
Message->message = WM_PAINT;
return TRUE;
}
BOOL
FASTCALL
IntPrintWindow(
PWND pwnd,
HDC hdcBlt,
UINT nFlags)
{
HDC hdcSrc;
INT cx, cy, xSrc, ySrc;
if ( nFlags & PW_CLIENTONLY)
{
cx = pwnd->rcClient.right - pwnd->rcClient.left;
cy = pwnd->rcClient.bottom - pwnd->rcClient.top;
xSrc = pwnd->rcClient.left - pwnd->rcWindow.left;
ySrc = pwnd->rcClient.top - pwnd->rcWindow.top;
}
else
{
cx = pwnd->rcWindow.right - pwnd->rcWindow.left;
cy = pwnd->rcWindow.bottom - pwnd->rcWindow.top;
xSrc = 0;
ySrc = 0;
}
// TODO: Setup Redirection for Print.
return FALSE;
/* Update the window just incase. */
co_IntUpdateWindows( pwnd, RDW_ALLCHILDREN, FALSE);
hdcSrc = UserGetDCEx( pwnd, NULL, DCX_CACHE|DCX_WINDOW);
/* Print window to printer context. */
NtGdiBitBlt( hdcBlt,
0,
0,
cx,
cy,
hdcSrc,
xSrc,
ySrc,
SRCCOPY,
0,
0);
UserReleaseDC( pwnd, hdcSrc, FALSE);
// TODO: Release Redirection from Print.
return TRUE;
}
BOOL
FASTCALL
IntFlashWindowEx(PWND pWnd, PFLASHWINFO pfwi)
{
DWORD_PTR FlashState;
UINT uCount = pfwi->uCount;
BOOL Activate = FALSE, Ret = FALSE;
ASSERT(pfwi);
FlashState = (DWORD_PTR)UserGetProp(pWnd, AtomFlashWndState, TRUE);
if (FlashState == FLASHW_FINISHED)
{
// Cycle has finished, kill timer and set this to Stop.
FlashState |= FLASHW_KILLSYSTIMER;
pfwi->dwFlags = FLASHW_STOP;
}
else
{
if (FlashState)
{
if (pfwi->dwFlags == FLASHW_SYSTIMER)
{
// Called from system timer, restore flags, counts and state.
pfwi->dwFlags = LOWORD(FlashState);
uCount = HIWORD(FlashState);
FlashState = MAKELONG(LOWORD(FlashState),0);
}
else
{
// Clean out the trash! Fix SeaMonkey crash after restart.
FlashState = 0;
}
}
if (FlashState == 0)
{ // First time in cycle, setup flash state.
if ( pWnd->state & WNDS_ACTIVEFRAME ||
(pfwi->dwFlags & FLASHW_CAPTION && pWnd->style & (WS_BORDER|WS_DLGFRAME)))
{
FlashState = FLASHW_STARTED|FLASHW_ACTIVE;
}
}
// Set previous window state.
Ret = !!(FlashState & FLASHW_ACTIVE);
if ( (pfwi->dwFlags & FLASHW_TIMERNOFG) == FLASHW_TIMERNOFG &&
gpqForeground == pWnd->head.pti->MessageQueue )
{
// Flashing until foreground, set this to Stop.
pfwi->dwFlags = FLASHW_STOP;
}
}
// Toggle activate flag.
if ( pfwi->dwFlags == FLASHW_STOP )
{
if (gpqForeground && gpqForeground->spwndActive == pWnd)
Activate = TRUE;
else
Activate = FALSE;
}
else
{
Activate = (FlashState & FLASHW_ACTIVE) == 0;
}
if ( pfwi->dwFlags == FLASHW_STOP || pfwi->dwFlags & FLASHW_CAPTION )
{
co_IntSendMessage(UserHMGetHandle(pWnd), WM_NCACTIVATE, Activate, 0);
}
// FIXME: Check for a Stop Sign here.
if ( pfwi->dwFlags & FLASHW_TRAY )
{
// Need some shell work here too.
TRACE("FIXME: Flash window no Tray support!\n");
}
if ( pfwi->dwFlags == FLASHW_STOP )
{
if (FlashState & FLASHW_KILLSYSTIMER)
{
IntKillTimer(pWnd, ID_EVENT_SYSTIMER_FLASHWIN, TRUE);
}
UserRemoveProp(pWnd, AtomFlashWndState, TRUE);
}
else
{ // Have a count and started, set timer.
if ( uCount )
{
FlashState |= FLASHW_COUNT;
if (!(Activate ^ !!(FlashState & FLASHW_STARTED)))
uCount--;
if (!(FlashState & FLASHW_KILLSYSTIMER))
pfwi->dwFlags |= FLASHW_TIMER;
}
if (pfwi->dwFlags & FLASHW_TIMER)
{
FlashState |= FLASHW_KILLSYSTIMER;
IntSetTimer( pWnd,
ID_EVENT_SYSTIMER_FLASHWIN,
pfwi->dwTimeout ? pfwi->dwTimeout : gpsi->dtCaretBlink,
SystemTimerProc,
TMRF_SYSTEM );
}
if (FlashState & FLASHW_COUNT && uCount == 0)
{
// Keep spinning? Nothing else to do.
FlashState = FLASHW_FINISHED;
}
else
{
// Save state and flags so this can be restored next time through.
FlashState ^= (FlashState ^ -!!(Activate)) & FLASHW_ACTIVE;
FlashState ^= (FlashState ^ pfwi->dwFlags) & (FLASHW_MASK & ~FLASHW_TIMER);
}
FlashState = MAKELONG(LOWORD(FlashState),uCount);
UserSetProp(pWnd, AtomFlashWndState, (HANDLE)FlashState, TRUE);
}
return Ret;
}
// Win: xxxBeginPaint
HDC FASTCALL
IntBeginPaint(PWND Window, PPAINTSTRUCT Ps)
{
RECT Rect;
INT type;
BOOL Erase = FALSE;
co_UserHideCaret(Window);
Window->state2 |= WNDS2_STARTPAINT;
Window->state &= ~WNDS_PAINTNOTPROCESSED;
if (Window->state & WNDS_SENDNCPAINT)
{
HRGN hRgn;
// Application can keep update dirty.
do
{
Window->state &= ~WNDS_UPDATEDIRTY;
hRgn = IntGetNCUpdateRgn(Window, FALSE);
IntSendNCPaint(Window, hRgn);
if (hRgn > HRGN_WINDOW && GreIsHandleValid(hRgn))
{
/* NOTE: The region can already be deleted! */
GreDeleteObject(hRgn);
}
}
while(Window->state & WNDS_UPDATEDIRTY);
}
else
{
Window->state &= ~WNDS_UPDATEDIRTY;
}
RtlZeroMemory(Ps, sizeof(PAINTSTRUCT));
if (Window->state2 & WNDS2_ENDPAINTINVALIDATE)
{
ERR("BP: Another thread invalidated this window\n");
}
Ps->hdc = UserGetDCEx( Window,
Window->hrgnUpdate,
DCX_INTERSECTRGN | DCX_USESTYLE);
if (!Ps->hdc)
{
return NULL;
}
// If set, always clear flags out due to the conditions later on for sending the message.
if (Window->state & WNDS_SENDERASEBACKGROUND)
{
Window->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
Erase = TRUE;
}
if (Window->hrgnUpdate != NULL)
{
MsqDecPaintCountQueue(Window->head.pti);
IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
/* The region is part of the dc now and belongs to the process! */
Window->hrgnUpdate = NULL;
}
else
{
if (Window->state & WNDS_INTERNALPAINT)
MsqDecPaintCountQueue(Window->head.pti);
}
type = GdiGetClipBox(Ps->hdc, &Ps->rcPaint);
IntGetClientRect(Window, &Rect);
Window->state &= ~WNDS_INTERNALPAINT;
if ( Erase && // Set to erase,
type != NULLREGION && // don't erase if the clip box is empty,
(!(Window->pcls->style & CS_PARENTDC) || // not parent dc or
RECTL_bIntersectRect( &Rect, &Rect, &Ps->rcPaint) ) ) // intersecting.
{
Ps->fErase = !co_IntSendMessage(UserHMGetHandle(Window), WM_ERASEBKGND, (WPARAM)Ps->hdc, 0);
if ( Ps->fErase )
{
Window->state |= (WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
}
}
else
{
Ps->fErase = FALSE;
}
IntSendChildNCPaint(Window);
return Ps->hdc;
}
// Win: xxxEndPaint
BOOL FASTCALL
IntEndPaint(PWND Wnd, PPAINTSTRUCT Ps)
{
HDC hdc = NULL;
hdc = Ps->hdc;
UserReleaseDC(Wnd, hdc, TRUE);
if (Wnd->state2 & WNDS2_ENDPAINTINVALIDATE)
{
ERR("EP: Another thread invalidated this window\n");
Wnd->state2 &= ~WNDS2_ENDPAINTINVALIDATE;
}
Wnd->state2 &= ~(WNDS2_WMPAINTSENT|WNDS2_STARTPAINT);
co_UserShowCaret(Wnd);
return TRUE;
}
// Win: xxxFillWindow
BOOL FASTCALL
IntFillWindow(PWND pWndParent,
PWND pWnd,
HDC hDC,
HBRUSH hBrush)
{
RECT Rect, Rect1;
INT type;
if (!pWndParent)
pWndParent = pWnd;
type = GdiGetClipBox(hDC, &Rect);
IntGetClientRect(pWnd, &Rect1);
if ( type != NULLREGION && // Clip box is not empty,
(!(pWnd->pcls->style & CS_PARENTDC) || // not parent dc or
RECTL_bIntersectRect( &Rect, &Rect, &Rect1) ) ) // intersecting.
{
POINT ppt;
INT x = 0, y = 0;
if (!UserIsDesktopWindow(pWndParent))
{
x = pWndParent->rcClient.left - pWnd->rcClient.left;
y = pWndParent->rcClient.top - pWnd->rcClient.top;
}
GreSetBrushOrg(hDC, x, y, &ppt);
if ( hBrush < (HBRUSH)CTLCOLOR_MAX )
hBrush = GetControlColor( pWndParent, pWnd, hDC, HandleToUlong(hBrush) + WM_CTLCOLORMSGBOX);
FillRect(hDC, &Rect, hBrush);
GreSetBrushOrg(hDC, ppt.x, ppt.y, NULL);
return TRUE;
}
else
return FALSE;
}
/* PUBLIC FUNCTIONS ***********************************************************/
/*
* NtUserBeginPaint
*
* Status
* @implemented
*/
HDC APIENTRY
NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* UnsafePs)
{
PWND Window;
PAINTSTRUCT Ps;
NTSTATUS Status;
HDC hDC;
USER_REFERENCE_ENTRY Ref;
HDC Ret = NULL;
TRACE("Enter NtUserBeginPaint\n");
UserEnterExclusive();
if (!(Window = UserGetWindowObject(hWnd)))
{
goto Cleanup; // Return NULL
}
UserRefObjectCo(Window, &Ref);
hDC = IntBeginPaint(Window, &Ps);
Status = MmCopyToCaller(UnsafePs, &Ps, sizeof(PAINTSTRUCT));
if (! NT_SUCCESS(Status))
{
SetLastNtError(Status);
goto Cleanup; // Return NULL
}
Ret = hDC;
Cleanup:
if (Window) UserDerefObjectCo(Window);
TRACE("Leave NtUserBeginPaint, ret=%p\n", Ret);
UserLeave();
return Ret;
}
/*
* NtUserEndPaint
*
* Status
* @implemented
*/
BOOL APIENTRY
NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT* pUnsafePs)
{
NTSTATUS Status = STATUS_SUCCESS;
PWND Window;
PAINTSTRUCT Ps;
USER_REFERENCE_ENTRY Ref;
BOOL Ret = FALSE;
TRACE("Enter NtUserEndPaint\n");
UserEnterExclusive();
if (!(Window = UserGetWindowObject(hWnd)))
{
goto Cleanup; // Return FALSE
}
UserRefObjectCo(Window, &Ref); // Here for the exception.
modified include/reactos/probe.h Workaround for gcc 4.1.3. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38054#c7 modified ntoskrnl/include/internal/mm.h gcc 4.3.2 doesn't like to be told to inline MmAcquirePageListLock modified ntoskrnl/include/internal/probe.h Cleaning up after TSVN's buggy "apply patch" modified subsystems/win32/win32k/ntuser/message.c Silence a gcc 4.3.2 warning (possibly incorrectly) modified dll/directx/ddraw/ddraw.rbuild modified dll/win32/gdi32/gdi32.rbuild modified dll/win32/kernel32/kernel32.rbuild modified dll/win32/psapi/psapi.rbuild modified dll/win32/setupapi/setupapi.rbuild modified dll/win32/syssetup/syssetup.rbuild modified dll/win32/user32/user32.rbuild modified drivers/input/kbdclass/kbdclass.rbuild modified drivers/input/mouclass/mouclass.rbuild modified drivers/network/afd/afd.rbuild modified drivers/network/tcpip/tcpip.rbuild modified lib/rtl/rtl.rbuild modified subsystems/win32/win32k/win32k.rbuild modified subsystems/win32/win32k/objects/gdiobj.c gcc 4.1.3 workarounds. See embedded comments modified base/services/eventlog/eventlog.h modified dll/win32/advapi32/advapi32.h Removed superfluous includes of pseh/pseh.h modified dll/directx/ddraw/Ddraw/ddraw_displaymode.c modified dll/directx/ddraw/Ddraw/ddraw_main.c modified dll/directx/ddraw/Ddraw/ddraw_setcooperativelevel.c modified dll/directx/ddraw/Ddraw/GetCaps.c modified dll/directx/ddraw/Ddraw/GetDeviceIdentifier.c modified dll/directx/ddraw/main.c modified dll/directx/ddraw/rosdraw.h modified dll/directx/ddraw/Surface/surface_main.c ddraw migrated to PSEH 2.0 modified dll/win32/gdi32/include/precomp.h modified dll/win32/gdi32/misc/misc.c modified dll/win32/gdi32/objects/bitmap.c gdi32 migrated to PSEH 2.0 modified dll/win32/kernel32/except/except.c modified dll/win32/kernel32/file/find.c modified dll/win32/kernel32/k32.h modified dll/win32/kernel32/mem/isbad.c modified dll/win32/kernel32/misc/console.c modified dll/win32/kernel32/process/procsup.c modified dll/win32/kernel32/string/lstring.c modified dll/win32/kernel32/thread/thread.c kernel32 migrated to PSEH 2.0 modified dll/win32/psapi/precomp.h modified dll/win32/psapi/psapi.c psapi migrated to PSEH 2.0 modified dll/win32/setupapi/cfgmgr.c modified dll/win32/setupapi/setupapi_private.h setupapi migrated to PSEH 2.0 modified dll/win32/syssetup/wizard.c syssetup migrated to PSEH 2.0 modified dll/win32/user32/include/user32.h modified dll/win32/user32/windows/class.c modified dll/win32/user32/windows/text.c modified dll/win32/user32/windows/window.c user32 migrated to PSEH 2.0 modified drivers/input/kbdclass/kbdclass.c modified drivers/input/kbdclass/kbdclass.h kbdclass migrated to PSEH 2.0 modified drivers/input/mouclass/mouclass.c modified drivers/input/mouclass/mouclass.h mouclass migrated to PSEH 2.0 modified drivers/network/afd/afd/info.c modified drivers/network/afd/afd/lock.c modified drivers/network/afd/afd/tdi.c modified drivers/network/afd/afd/tdiconn.c afd migrated to PSEH 2.0 modified drivers/network/lan/lan/lan.c lan migrated to PSEH 2.0 modified drivers/network/tcpip/tcpip/dispatch.c tcpip migrated to PSEH 2.0 modified lib/rtl/debug.c modified lib/rtl/res.c modified lib/rtl/rtl.h modified lib/rtl/unicode.c modified lib/rtl/workitem.c rtl migrated to PSEH 2.0 modified ntoskrnl/include/precomp.h ntoskrnl migrated to PSEH 2.0 modified subsystems/csr/csrsrv/api.c csrsrv migrated to PSEH 2.0 modified subsystems/win32/win32k/eng/bitblt.c modified subsystems/win32/win32k/eng/mem.c modified subsystems/win32/win32k/include/mmcopy.h modified subsystems/win32/win32k/misc/copy.c modified subsystems/win32/win32k/ntuser/callback.c modified subsystems/win32/win32k/ntuser/class.c modified subsystems/win32/win32k/ntuser/clipboard.c modified subsystems/win32/win32k/ntuser/cursoricon.c modified subsystems/win32/win32k/ntuser/display.c modified subsystems/win32/win32k/ntuser/hook.c modified subsystems/win32/win32k/ntuser/input.c modified subsystems/win32/win32k/ntuser/kbdlayout.c modified subsystems/win32/win32k/ntuser/menu.c modified subsystems/win32/win32k/ntuser/misc.c modified subsystems/win32/win32k/ntuser/ntstubs.c modified subsystems/win32/win32k/ntuser/painting.c modified subsystems/win32/win32k/ntuser/simplecall.c modified subsystems/win32/win32k/ntuser/sysparams.c modified subsystems/win32/win32k/ntuser/window.c modified subsystems/win32/win32k/objects/bitblt.c modified subsystems/win32/win32k/objects/bitmaps.c modified subsystems/win32/win32k/objects/brush.c modified subsystems/win32/win32k/objects/cliprgn.c modified subsystems/win32/win32k/objects/color.c modified subsystems/win32/win32k/objects/coord.c modified subsystems/win32/win32k/objects/dc.c modified subsystems/win32/win32k/objects/dcutil.c modified subsystems/win32/win32k/objects/dibobj.c modified subsystems/win32/win32k/objects/fillshap.c modified subsystems/win32/win32k/objects/font.c modified subsystems/win32/win32k/objects/freetype.c modified subsystems/win32/win32k/objects/icm.c modified subsystems/win32/win32k/objects/line.c modified subsystems/win32/win32k/objects/path.c modified subsystems/win32/win32k/objects/pen.c modified subsystems/win32/win32k/objects/print.c modified subsystems/win32/win32k/objects/region.c modified subsystems/win32/win32k/objects/text.c modified subsystems/win32/win32k/pch.h win32k migrated to PSEH 2.0 svn path=/trunk/; revision=37776
2008-11-30 19:28:11 +00:00
_SEH2_TRY
{
ProbeForRead(pUnsafePs, sizeof(*pUnsafePs), 1);
RtlCopyMemory(&Ps, pUnsafePs, sizeof(PAINTSTRUCT));
}
modified include/reactos/probe.h Workaround for gcc 4.1.3. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38054#c7 modified ntoskrnl/include/internal/mm.h gcc 4.3.2 doesn't like to be told to inline MmAcquirePageListLock modified ntoskrnl/include/internal/probe.h Cleaning up after TSVN's buggy "apply patch" modified subsystems/win32/win32k/ntuser/message.c Silence a gcc 4.3.2 warning (possibly incorrectly) modified dll/directx/ddraw/ddraw.rbuild modified dll/win32/gdi32/gdi32.rbuild modified dll/win32/kernel32/kernel32.rbuild modified dll/win32/psapi/psapi.rbuild modified dll/win32/setupapi/setupapi.rbuild modified dll/win32/syssetup/syssetup.rbuild modified dll/win32/user32/user32.rbuild modified drivers/input/kbdclass/kbdclass.rbuild modified drivers/input/mouclass/mouclass.rbuild modified drivers/network/afd/afd.rbuild modified drivers/network/tcpip/tcpip.rbuild modified lib/rtl/rtl.rbuild modified subsystems/win32/win32k/win32k.rbuild modified subsystems/win32/win32k/objects/gdiobj.c gcc 4.1.3 workarounds. See embedded comments modified base/services/eventlog/eventlog.h modified dll/win32/advapi32/advapi32.h Removed superfluous includes of pseh/pseh.h modified dll/directx/ddraw/Ddraw/ddraw_displaymode.c modified dll/directx/ddraw/Ddraw/ddraw_main.c modified dll/directx/ddraw/Ddraw/ddraw_setcooperativelevel.c modified dll/directx/ddraw/Ddraw/GetCaps.c modified dll/directx/ddraw/Ddraw/GetDeviceIdentifier.c modified dll/directx/ddraw/main.c modified dll/directx/ddraw/rosdraw.h modified dll/directx/ddraw/Surface/surface_main.c ddraw migrated to PSEH 2.0 modified dll/win32/gdi32/include/precomp.h modified dll/win32/gdi32/misc/misc.c modified dll/win32/gdi32/objects/bitmap.c gdi32 migrated to PSEH 2.0 modified dll/win32/kernel32/except/except.c modified dll/win32/kernel32/file/find.c modified dll/win32/kernel32/k32.h modified dll/win32/kernel32/mem/isbad.c modified dll/win32/kernel32/misc/console.c modified dll/win32/kernel32/process/procsup.c modified dll/win32/kernel32/string/lstring.c modified dll/win32/kernel32/thread/thread.c kernel32 migrated to PSEH 2.0 modified dll/win32/psapi/precomp.h modified dll/win32/psapi/psapi.c psapi migrated to PSEH 2.0 modified dll/win32/setupapi/cfgmgr.c modified dll/win32/setupapi/setupapi_private.h setupapi migrated to PSEH 2.0 modified dll/win32/syssetup/wizard.c syssetup migrated to PSEH 2.0 modified dll/win32/user32/include/user32.h modified dll/win32/user32/windows/class.c modified dll/win32/user32/windows/text.c modified dll/win32/user32/windows/window.c user32 migrated to PSEH 2.0 modified drivers/input/kbdclass/kbdclass.c modified drivers/input/kbdclass/kbdclass.h kbdclass migrated to PSEH 2.0 modified drivers/input/mouclass/mouclass.c modified drivers/input/mouclass/mouclass.h mouclass migrated to PSEH 2.0 modified drivers/network/afd/afd/info.c modified drivers/network/afd/afd/lock.c modified drivers/network/afd/afd/tdi.c modified drivers/network/afd/afd/tdiconn.c afd migrated to PSEH 2.0 modified drivers/network/lan/lan/lan.c lan migrated to PSEH 2.0 modified drivers/network/tcpip/tcpip/dispatch.c tcpip migrated to PSEH 2.0 modified lib/rtl/debug.c modified lib/rtl/res.c modified lib/rtl/rtl.h modified lib/rtl/unicode.c modified lib/rtl/workitem.c rtl migrated to PSEH 2.0 modified ntoskrnl/include/precomp.h ntoskrnl migrated to PSEH 2.0 modified subsystems/csr/csrsrv/api.c csrsrv migrated to PSEH 2.0 modified subsystems/win32/win32k/eng/bitblt.c modified subsystems/win32/win32k/eng/mem.c modified subsystems/win32/win32k/include/mmcopy.h modified subsystems/win32/win32k/misc/copy.c modified subsystems/win32/win32k/ntuser/callback.c modified subsystems/win32/win32k/ntuser/class.c modified subsystems/win32/win32k/ntuser/clipboard.c modified subsystems/win32/win32k/ntuser/cursoricon.c modified subsystems/win32/win32k/ntuser/display.c modified subsystems/win32/win32k/ntuser/hook.c modified subsystems/win32/win32k/ntuser/input.c modified subsystems/win32/win32k/ntuser/kbdlayout.c modified subsystems/win32/win32k/ntuser/menu.c modified subsystems/win32/win32k/ntuser/misc.c modified subsystems/win32/win32k/ntuser/ntstubs.c modified subsystems/win32/win32k/ntuser/painting.c modified subsystems/win32/win32k/ntuser/simplecall.c modified subsystems/win32/win32k/ntuser/sysparams.c modified subsystems/win32/win32k/ntuser/window.c modified subsystems/win32/win32k/objects/bitblt.c modified subsystems/win32/win32k/objects/bitmaps.c modified subsystems/win32/win32k/objects/brush.c modified subsystems/win32/win32k/objects/cliprgn.c modified subsystems/win32/win32k/objects/color.c modified subsystems/win32/win32k/objects/coord.c modified subsystems/win32/win32k/objects/dc.c modified subsystems/win32/win32k/objects/dcutil.c modified subsystems/win32/win32k/objects/dibobj.c modified subsystems/win32/win32k/objects/fillshap.c modified subsystems/win32/win32k/objects/font.c modified subsystems/win32/win32k/objects/freetype.c modified subsystems/win32/win32k/objects/icm.c modified subsystems/win32/win32k/objects/line.c modified subsystems/win32/win32k/objects/path.c modified subsystems/win32/win32k/objects/pen.c modified subsystems/win32/win32k/objects/print.c modified subsystems/win32/win32k/objects/region.c modified subsystems/win32/win32k/objects/text.c modified subsystems/win32/win32k/pch.h win32k migrated to PSEH 2.0 svn path=/trunk/; revision=37776
2008-11-30 19:28:11 +00:00
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
modified include/reactos/probe.h Workaround for gcc 4.1.3. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38054#c7 modified ntoskrnl/include/internal/mm.h gcc 4.3.2 doesn't like to be told to inline MmAcquirePageListLock modified ntoskrnl/include/internal/probe.h Cleaning up after TSVN's buggy "apply patch" modified subsystems/win32/win32k/ntuser/message.c Silence a gcc 4.3.2 warning (possibly incorrectly) modified dll/directx/ddraw/ddraw.rbuild modified dll/win32/gdi32/gdi32.rbuild modified dll/win32/kernel32/kernel32.rbuild modified dll/win32/psapi/psapi.rbuild modified dll/win32/setupapi/setupapi.rbuild modified dll/win32/syssetup/syssetup.rbuild modified dll/win32/user32/user32.rbuild modified drivers/input/kbdclass/kbdclass.rbuild modified drivers/input/mouclass/mouclass.rbuild modified drivers/network/afd/afd.rbuild modified drivers/network/tcpip/tcpip.rbuild modified lib/rtl/rtl.rbuild modified subsystems/win32/win32k/win32k.rbuild modified subsystems/win32/win32k/objects/gdiobj.c gcc 4.1.3 workarounds. See embedded comments modified base/services/eventlog/eventlog.h modified dll/win32/advapi32/advapi32.h Removed superfluous includes of pseh/pseh.h modified dll/directx/ddraw/Ddraw/ddraw_displaymode.c modified dll/directx/ddraw/Ddraw/ddraw_main.c modified dll/directx/ddraw/Ddraw/ddraw_setcooperativelevel.c modified dll/directx/ddraw/Ddraw/GetCaps.c modified dll/directx/ddraw/Ddraw/GetDeviceIdentifier.c modified dll/directx/ddraw/main.c modified dll/directx/ddraw/rosdraw.h modified dll/directx/ddraw/Surface/surface_main.c ddraw migrated to PSEH 2.0 modified dll/win32/gdi32/include/precomp.h modified dll/win32/gdi32/misc/misc.c modified dll/win32/gdi32/objects/bitmap.c gdi32 migrated to PSEH 2.0 modified dll/win32/kernel32/except/except.c modified dll/win32/kernel32/file/find.c modified dll/win32/kernel32/k32.h modified dll/win32/kernel32/mem/isbad.c modified dll/win32/kernel32/misc/console.c modified dll/win32/kernel32/process/procsup.c modified dll/win32/kernel32/string/lstring.c modified dll/win32/kernel32/thread/thread.c kernel32 migrated to PSEH 2.0 modified dll/win32/psapi/precomp.h modified dll/win32/psapi/psapi.c psapi migrated to PSEH 2.0 modified dll/win32/setupapi/cfgmgr.c modified dll/win32/setupapi/setupapi_private.h setupapi migrated to PSEH 2.0 modified dll/win32/syssetup/wizard.c syssetup migrated to PSEH 2.0 modified dll/win32/user32/include/user32.h modified dll/win32/user32/windows/class.c modified dll/win32/user32/windows/text.c modified dll/win32/user32/windows/window.c user32 migrated to PSEH 2.0 modified drivers/input/kbdclass/kbdclass.c modified drivers/input/kbdclass/kbdclass.h kbdclass migrated to PSEH 2.0 modified drivers/input/mouclass/mouclass.c modified drivers/input/mouclass/mouclass.h mouclass migrated to PSEH 2.0 modified drivers/network/afd/afd/info.c modified drivers/network/afd/afd/lock.c modified drivers/network/afd/afd/tdi.c modified drivers/network/afd/afd/tdiconn.c afd migrated to PSEH 2.0 modified drivers/network/lan/lan/lan.c lan migrated to PSEH 2.0 modified drivers/network/tcpip/tcpip/dispatch.c tcpip migrated to PSEH 2.0 modified lib/rtl/debug.c modified lib/rtl/res.c modified lib/rtl/rtl.h modified lib/rtl/unicode.c modified lib/rtl/workitem.c rtl migrated to PSEH 2.0 modified ntoskrnl/include/precomp.h ntoskrnl migrated to PSEH 2.0 modified subsystems/csr/csrsrv/api.c csrsrv migrated to PSEH 2.0 modified subsystems/win32/win32k/eng/bitblt.c modified subsystems/win32/win32k/eng/mem.c modified subsystems/win32/win32k/include/mmcopy.h modified subsystems/win32/win32k/misc/copy.c modified subsystems/win32/win32k/ntuser/callback.c modified subsystems/win32/win32k/ntuser/class.c modified subsystems/win32/win32k/ntuser/clipboard.c modified subsystems/win32/win32k/ntuser/cursoricon.c modified subsystems/win32/win32k/ntuser/display.c modified subsystems/win32/win32k/ntuser/hook.c modified subsystems/win32/win32k/ntuser/input.c modified subsystems/win32/win32k/ntuser/kbdlayout.c modified subsystems/win32/win32k/ntuser/menu.c modified subsystems/win32/win32k/ntuser/misc.c modified subsystems/win32/win32k/ntuser/ntstubs.c modified subsystems/win32/win32k/ntuser/painting.c modified subsystems/win32/win32k/ntuser/simplecall.c modified subsystems/win32/win32k/ntuser/sysparams.c modified subsystems/win32/win32k/ntuser/window.c modified subsystems/win32/win32k/objects/bitblt.c modified subsystems/win32/win32k/objects/bitmaps.c modified subsystems/win32/win32k/objects/brush.c modified subsystems/win32/win32k/objects/cliprgn.c modified subsystems/win32/win32k/objects/color.c modified subsystems/win32/win32k/objects/coord.c modified subsystems/win32/win32k/objects/dc.c modified subsystems/win32/win32k/objects/dcutil.c modified subsystems/win32/win32k/objects/dibobj.c modified subsystems/win32/win32k/objects/fillshap.c modified subsystems/win32/win32k/objects/font.c modified subsystems/win32/win32k/objects/freetype.c modified subsystems/win32/win32k/objects/icm.c modified subsystems/win32/win32k/objects/line.c modified subsystems/win32/win32k/objects/path.c modified subsystems/win32/win32k/objects/pen.c modified subsystems/win32/win32k/objects/print.c modified subsystems/win32/win32k/objects/region.c modified subsystems/win32/win32k/objects/text.c modified subsystems/win32/win32k/pch.h win32k migrated to PSEH 2.0 svn path=/trunk/; revision=37776
2008-11-30 19:28:11 +00:00
Status = _SEH2_GetExceptionCode();
}
modified include/reactos/probe.h Workaround for gcc 4.1.3. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38054#c7 modified ntoskrnl/include/internal/mm.h gcc 4.3.2 doesn't like to be told to inline MmAcquirePageListLock modified ntoskrnl/include/internal/probe.h Cleaning up after TSVN's buggy "apply patch" modified subsystems/win32/win32k/ntuser/message.c Silence a gcc 4.3.2 warning (possibly incorrectly) modified dll/directx/ddraw/ddraw.rbuild modified dll/win32/gdi32/gdi32.rbuild modified dll/win32/kernel32/kernel32.rbuild modified dll/win32/psapi/psapi.rbuild modified dll/win32/setupapi/setupapi.rbuild modified dll/win32/syssetup/syssetup.rbuild modified dll/win32/user32/user32.rbuild modified drivers/input/kbdclass/kbdclass.rbuild modified drivers/input/mouclass/mouclass.rbuild modified drivers/network/afd/afd.rbuild modified drivers/network/tcpip/tcpip.rbuild modified lib/rtl/rtl.rbuild modified subsystems/win32/win32k/win32k.rbuild modified subsystems/win32/win32k/objects/gdiobj.c gcc 4.1.3 workarounds. See embedded comments modified base/services/eventlog/eventlog.h modified dll/win32/advapi32/advapi32.h Removed superfluous includes of pseh/pseh.h modified dll/directx/ddraw/Ddraw/ddraw_displaymode.c modified dll/directx/ddraw/Ddraw/ddraw_main.c modified dll/directx/ddraw/Ddraw/ddraw_setcooperativelevel.c modified dll/directx/ddraw/Ddraw/GetCaps.c modified dll/directx/ddraw/Ddraw/GetDeviceIdentifier.c modified dll/directx/ddraw/main.c modified dll/directx/ddraw/rosdraw.h modified dll/directx/ddraw/Surface/surface_main.c ddraw migrated to PSEH 2.0 modified dll/win32/gdi32/include/precomp.h modified dll/win32/gdi32/misc/misc.c modified dll/win32/gdi32/objects/bitmap.c gdi32 migrated to PSEH 2.0 modified dll/win32/kernel32/except/except.c modified dll/win32/kernel32/file/find.c modified dll/win32/kernel32/k32.h modified dll/win32/kernel32/mem/isbad.c modified dll/win32/kernel32/misc/console.c modified dll/win32/kernel32/process/procsup.c modified dll/win32/kernel32/string/lstring.c modified dll/win32/kernel32/thread/thread.c kernel32 migrated to PSEH 2.0 modified dll/win32/psapi/precomp.h modified dll/win32/psapi/psapi.c psapi migrated to PSEH 2.0 modified dll/win32/setupapi/cfgmgr.c modified dll/win32/setupapi/setupapi_private.h setupapi migrated to PSEH 2.0 modified dll/win32/syssetup/wizard.c syssetup migrated to PSEH 2.0 modified dll/win32/user32/include/user32.h modified dll/win32/user32/windows/class.c modified dll/win32/user32/windows/text.c modified dll/win32/user32/windows/window.c user32 migrated to PSEH 2.0 modified drivers/input/kbdclass/kbdclass.c modified drivers/input/kbdclass/kbdclass.h kbdclass migrated to PSEH 2.0 modified drivers/input/mouclass/mouclass.c modified drivers/input/mouclass/mouclass.h mouclass migrated to PSEH 2.0 modified drivers/network/afd/afd/info.c modified drivers/network/afd/afd/lock.c modified drivers/network/afd/afd/tdi.c modified drivers/network/afd/afd/tdiconn.c afd migrated to PSEH 2.0 modified drivers/network/lan/lan/lan.c lan migrated to PSEH 2.0 modified drivers/network/tcpip/tcpip/dispatch.c tcpip migrated to PSEH 2.0 modified lib/rtl/debug.c modified lib/rtl/res.c modified lib/rtl/rtl.h modified lib/rtl/unicode.c modified lib/rtl/workitem.c rtl migrated to PSEH 2.0 modified ntoskrnl/include/precomp.h ntoskrnl migrated to PSEH 2.0 modified subsystems/csr/csrsrv/api.c csrsrv migrated to PSEH 2.0 modified subsystems/win32/win32k/eng/bitblt.c modified subsystems/win32/win32k/eng/mem.c modified subsystems/win32/win32k/include/mmcopy.h modified subsystems/win32/win32k/misc/copy.c modified subsystems/win32/win32k/ntuser/callback.c modified subsystems/win32/win32k/ntuser/class.c modified subsystems/win32/win32k/ntuser/clipboard.c modified subsystems/win32/win32k/ntuser/cursoricon.c modified subsystems/win32/win32k/ntuser/display.c modified subsystems/win32/win32k/ntuser/hook.c modified subsystems/win32/win32k/ntuser/input.c modified subsystems/win32/win32k/ntuser/kbdlayout.c modified subsystems/win32/win32k/ntuser/menu.c modified subsystems/win32/win32k/ntuser/misc.c modified subsystems/win32/win32k/ntuser/ntstubs.c modified subsystems/win32/win32k/ntuser/painting.c modified subsystems/win32/win32k/ntuser/simplecall.c modified subsystems/win32/win32k/ntuser/sysparams.c modified subsystems/win32/win32k/ntuser/window.c modified subsystems/win32/win32k/objects/bitblt.c modified subsystems/win32/win32k/objects/bitmaps.c modified subsystems/win32/win32k/objects/brush.c modified subsystems/win32/win32k/objects/cliprgn.c modified subsystems/win32/win32k/objects/color.c modified subsystems/win32/win32k/objects/coord.c modified subsystems/win32/win32k/objects/dc.c modified subsystems/win32/win32k/objects/dcutil.c modified subsystems/win32/win32k/objects/dibobj.c modified subsystems/win32/win32k/objects/fillshap.c modified subsystems/win32/win32k/objects/font.c modified subsystems/win32/win32k/objects/freetype.c modified subsystems/win32/win32k/objects/icm.c modified subsystems/win32/win32k/objects/line.c modified subsystems/win32/win32k/objects/path.c modified subsystems/win32/win32k/objects/pen.c modified subsystems/win32/win32k/objects/print.c modified subsystems/win32/win32k/objects/region.c modified subsystems/win32/win32k/objects/text.c modified subsystems/win32/win32k/pch.h win32k migrated to PSEH 2.0 svn path=/trunk/; revision=37776
2008-11-30 19:28:11 +00:00
_SEH2_END
if (!NT_SUCCESS(Status))
{
goto Cleanup; // Return FALSE
}
Ret = IntEndPaint(Window, &Ps);
Cleanup:
if (Window) UserDerefObjectCo(Window);
TRACE("Leave NtUserEndPaint, ret=%i\n", Ret);
UserLeave();
return Ret;
}
/*
* FillWindow: Called from User; Dialog, Edit and ListBox procs during a WM_ERASEBKGND.
*/
/*
* @implemented
*/
BOOL APIENTRY
NtUserFillWindow(HWND hWndParent,
HWND hWnd,
HDC hDC,
HBRUSH hBrush)
{
BOOL ret = FALSE;
PWND pWnd, pWndParent = NULL;
USER_REFERENCE_ENTRY Ref;
TRACE("Enter NtUserFillWindow\n");
UserEnterExclusive();
if (!hDC)
{
goto Exit;
}
if (!(pWnd = UserGetWindowObject(hWnd)))
{
goto Exit;
}
if (hWndParent && !(pWndParent = UserGetWindowObject(hWndParent)))
{
goto Exit;
}
UserRefObjectCo(pWnd, &Ref);
ret = IntFillWindow( pWndParent, pWnd, hDC, hBrush );
UserDerefObjectCo(pWnd);
Exit:
TRACE("Leave NtUserFillWindow, ret=%i\n",ret);
UserLeave();
return ret;
}
/*
* @implemented
*/
BOOL APIENTRY
NtUserFlashWindowEx(IN PFLASHWINFO pfwi)
{
PWND pWnd;
FLASHWINFO finfo = {0};
BOOL Ret = FALSE;
UserEnterExclusive();
_SEH2_TRY
{
ProbeForRead(pfwi, sizeof(FLASHWINFO), 1);
RtlCopyMemory(&finfo, pfwi, sizeof(FLASHWINFO));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastNtError(_SEH2_GetExceptionCode());
_SEH2_YIELD(goto Exit);
}
_SEH2_END
if (!( pWnd = ValidateHwndNoErr(finfo.hwnd)) ||
finfo.cbSize != sizeof(FLASHWINFO) ||
finfo.dwFlags & ~(FLASHW_ALL|FLASHW_TIMER|FLASHW_TIMERNOFG) )
{
EngSetLastError(ERROR_INVALID_PARAMETER);
goto Exit;
}
Ret = IntFlashWindowEx(pWnd, &finfo);
Exit:
UserLeave();
return Ret;
}
/*
GetUpdateRgn, this fails the same as the old one.
*/
INT FASTCALL
co_UserGetUpdateRgn(PWND Window, HRGN hRgn, BOOL bErase)
{
int RegionType;
BOOL Type;
RECTL Rect;
ASSERT_REFS_CO(Window);
if (bErase)
{
USER_REFERENCE_ENTRY Ref;
UserRefObjectCo(Window, &Ref);
co_IntPaintWindows(Window, RDW_NOCHILDREN, FALSE);
UserDerefObjectCo(Window);
}
Window->state &= ~WNDS_UPDATEDIRTY;
if (Window->hrgnUpdate == NULL)
{
NtGdiSetRectRgn(hRgn, 0, 0, 0, 0);
return NULLREGION;
}
Rect = Window->rcClient;
Type = IntIntersectWithParents(Window, &Rect);
if (Window->hrgnUpdate == HRGN_WINDOW)
{
// Trap it out.
ERR("GURn: Caller is passing Window Region 1\n");
if (!Type)
{
NtGdiSetRectRgn(hRgn, 0, 0, 0, 0);
return NULLREGION;
}
RegionType = SIMPLEREGION;
if (!UserIsDesktopWindow(Window))
{
RECTL_vOffsetRect(&Rect,
-Window->rcClient.left,
-Window->rcClient.top);
}
GreSetRectRgnIndirect(hRgn, &Rect);
}
else
{
HRGN hrgnTemp = GreCreateRectRgnIndirect(&Rect);
RegionType = NtGdiCombineRgn(hRgn, hrgnTemp, Window->hrgnUpdate, RGN_AND);
if (RegionType == ERROR || RegionType == NULLREGION)
{
if (hrgnTemp) GreDeleteObject(hrgnTemp);
NtGdiSetRectRgn(hRgn, 0, 0, 0, 0);
return RegionType;
}
if (!UserIsDesktopWindow(Window))
{
NtGdiOffsetRgn(hRgn,
-Window->rcClient.left,
-Window->rcClient.top);
}
if (hrgnTemp) GreDeleteObject(hrgnTemp);
}
return RegionType;
}
BOOL FASTCALL
co_UserGetUpdateRect(PWND Window, PRECT pRect, BOOL bErase)
{
INT RegionType;
BOOL Ret = TRUE;
if (bErase)
{
USER_REFERENCE_ENTRY Ref;
UserRefObjectCo(Window, &Ref);
co_IntPaintWindows(Window, RDW_NOCHILDREN, FALSE);
UserDerefObjectCo(Window);
}
Window->state &= ~WNDS_UPDATEDIRTY;
if (Window->hrgnUpdate == NULL)
{
pRect->left = pRect->top = pRect->right = pRect->bottom = 0;
Ret = FALSE;
}
else
{
/* Get the update region bounding box. */
if (Window->hrgnUpdate == HRGN_WINDOW)
{
*pRect = Window->rcClient;
ERR("GURt: Caller is retrieving Window Region 1\n");
}
else
{
RegionType = IntGdiGetRgnBox(Window->hrgnUpdate, pRect);
if (RegionType != ERROR && RegionType != NULLREGION)
RECTL_bIntersectRect(pRect, pRect, &Window->rcClient);
}
if (IntIntersectWithParents(Window, pRect))
{
if (!UserIsDesktopWindow(Window))
{
RECTL_vOffsetRect(pRect,
-Window->rcClient.left,
-Window->rcClient.top);
}
if (Window->pcls->style & CS_OWNDC)
{
HDC hdc;
//DWORD layout;
hdc = UserGetDCEx(Window, NULL, DCX_USESTYLE);
//layout = NtGdiSetLayout(hdc, -1, 0);
//IntMapWindowPoints( 0, Window, (LPPOINT)pRect, 2 );
GreDPtoLP( hdc, (LPPOINT)pRect, 2 );
//NtGdiSetLayout(hdc, -1, layout);
UserReleaseDC(Window, hdc, FALSE);
}
}
else
{
pRect->left = pRect->top = pRect->right = pRect->bottom = 0;
}
}
return Ret;
}
/*
* NtUserGetUpdateRgn
*
* Status
* @implemented
*/
INT APIENTRY
NtUserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
{
PWND Window;
INT ret = ERROR;
TRACE("Enter NtUserGetUpdateRgn\n");
UserEnterExclusive();
Window = UserGetWindowObject(hWnd);
if (Window)
{
ret = co_UserGetUpdateRgn(Window, hRgn, bErase);
}
TRACE("Leave NtUserGetUpdateRgn, ret=%i\n", ret);
UserLeave();
return ret;
}
/*
* NtUserGetUpdateRect
*
* Status
* @implemented
*/
BOOL APIENTRY
NtUserGetUpdateRect(HWND hWnd, LPRECT UnsafeRect, BOOL bErase)
{
PWND Window;
RECTL Rect;
NTSTATUS Status;
BOOL Ret = FALSE;
TRACE("Enter NtUserGetUpdateRect\n");
UserEnterExclusive();
if (!(Window = UserGetWindowObject(hWnd)))
{
goto Exit; // Return FALSE
}
Ret = co_UserGetUpdateRect(Window, &Rect, bErase);
if (UnsafeRect != NULL)
{
Status = MmCopyToCaller(UnsafeRect, &Rect, sizeof(RECTL));
if (!NT_SUCCESS(Status))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
Ret = FALSE;
}
}
Exit:
TRACE("Leave NtUserGetUpdateRect, ret=%i\n", Ret);
UserLeave();
return Ret;
}
/*
* NtUserRedrawWindow
*
* Status
* @implemented
*/
BOOL APIENTRY
NtUserRedrawWindow(
HWND hWnd,
CONST RECT *lprcUpdate,
HRGN hrgnUpdate,
UINT flags)
{
RECTL SafeUpdateRect;
PWND Wnd;
BOOL Ret = FALSE;
USER_REFERENCE_ENTRY Ref;
NTSTATUS Status = STATUS_SUCCESS;
PREGION RgnUpdate = NULL;
TRACE("Enter NtUserRedrawWindow\n");
UserEnterExclusive();
if (!(Wnd = UserGetWindowObject(hWnd ? hWnd : IntGetDesktopWindow())))
{
goto Exit; // Return FALSE
}
if (lprcUpdate)
{
_SEH2_TRY
{
ProbeForRead(lprcUpdate, sizeof(RECTL), 1);
RtlCopyMemory(&SafeUpdateRect, lprcUpdate, sizeof(RECTL));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END
if (!NT_SUCCESS(Status))
{
EngSetLastError(RtlNtStatusToDosError(Status));
goto Exit; // Return FALSE
}
}
if ( flags & ~(RDW_ERASE|RDW_FRAME|RDW_INTERNALPAINT|RDW_INVALIDATE|
RDW_NOERASE|RDW_NOFRAME|RDW_NOINTERNALPAINT|RDW_VALIDATE|
RDW_ERASENOW|RDW_UPDATENOW|RDW_ALLCHILDREN|RDW_NOCHILDREN) )
{
/* RedrawWindow fails only in case that flags are invalid */
EngSetLastError(ERROR_INVALID_FLAGS);
goto Exit; // Return FALSE
}
/* We can't hold lock on GDI objects while doing roundtrips to user mode,
* so it will be copied.
*/
if (hrgnUpdate > HRGN_WINDOW)
{
RgnUpdate = REGION_LockRgn(hrgnUpdate);
if (!RgnUpdate)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto Exit; // Return FALSE
}
REGION_UnlockRgn(RgnUpdate);
}
else if (hrgnUpdate == HRGN_WINDOW) // Trap it out.
{
ERR("NTRW: Caller is passing Window Region 1\n");
}
UserRefObjectCo(Wnd, &Ref);
Ret = co_UserRedrawWindow( Wnd,
lprcUpdate ? &SafeUpdateRect : NULL,
RgnUpdate,
flags);
UserDerefObjectCo(Wnd);
Exit:
TRACE("Leave NtUserRedrawWindow, ret=%i\n", Ret);
UserLeave();
return Ret;
}
BOOL
UserDrawCaptionText(
PWND pWnd,
HDC hDc,
const PUNICODE_STRING Text,
const RECTL *lpRc,
UINT uFlags,
HFONT hFont)
{
HFONT hOldFont = NULL;
COLORREF OldTextColor;
NONCLIENTMETRICSW nclm;
NTSTATUS Status;
BOOLEAN bDeleteFont = FALSE;
SIZE Size;
BOOL Ret = TRUE;
ULONG fit = 0, Length;
RECTL r = *lpRc;
TRACE("UserDrawCaptionText: %wZ\n", Text);
nclm.cbSize = sizeof(nclm);
if (!UserSystemParametersInfo(SPI_GETNONCLIENTMETRICS, nclm.cbSize, &nclm, 0))
{
ERR("UserSystemParametersInfo() failed!\n");
return FALSE;
}
if (!hFont)
{
if(uFlags & DC_SMALLCAP)
Status = TextIntCreateFontIndirect(&nclm.lfSmCaptionFont, &hFont);
else
Status = TextIntCreateFontIndirect(&nclm.lfCaptionFont, &hFont);
if(!NT_SUCCESS(Status))
{
ERR("TextIntCreateFontIndirect() failed! Status: 0x%x\n", Status);
return FALSE;
}
bDeleteFont = TRUE;
}
IntGdiSetBkMode(hDc, TRANSPARENT);
hOldFont = NtGdiSelectFont(hDc, hFont);
if(uFlags & DC_INBUTTON)
OldTextColor = IntGdiSetTextColor(hDc, IntGetSysColor(COLOR_BTNTEXT));
else
OldTextColor = IntGdiSetTextColor(hDc,
IntGetSysColor(uFlags & DC_ACTIVE ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT));
// Adjust for system menu.
if (pWnd && pWnd->style & WS_SYSMENU)
{
r.right -= UserGetSystemMetrics(SM_CYCAPTION) - 1;
if ((pWnd->style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) && !(pWnd->ExStyle & WS_EX_TOOLWINDOW))
{
r.right -= UserGetSystemMetrics(SM_CXSIZE) + 1;
r.right -= UserGetSystemMetrics(SM_CXSIZE) + 1;
}
}
GreGetTextExtentExW(hDc, Text->Buffer, Text->Length/sizeof(WCHAR), r.right - r.left, &fit, 0, &Size, 0);
Length = (Text->Length/sizeof(WCHAR) == fit ? fit : fit+1);
if (Text->Length/sizeof(WCHAR) > Length)
{
Ret = FALSE;
}
if (Ret)
{ // Faster while in setup.
UserExtTextOutW( hDc,
lpRc->left,
lpRc->top + (lpRc->bottom - lpRc->top - Size.cy) / 2, // DT_SINGLELINE && DT_VCENTER
ETO_CLIPPED,
(RECTL *)lpRc,
Text->Buffer,
Length);
}
else
{
DrawTextW( hDc,
Text->Buffer,
Text->Length/sizeof(WCHAR),
(RECTL *)&r,
DT_END_ELLIPSIS|DT_SINGLELINE|DT_VCENTER|DT_NOPREFIX|DT_LEFT);
}
IntGdiSetTextColor(hDc, OldTextColor);
if (hOldFont)
NtGdiSelectFont(hDc, hOldFont);
if (bDeleteFont)
GreDeleteObject(hFont);
return Ret;
}
//
// This draws Buttons, Icons and Text...
//
BOOL UserDrawCaption(
PWND pWnd,
HDC hDc,
RECTL *lpRc,
HFONT hFont,
HICON hIcon,
const PUNICODE_STRING Str,
UINT uFlags)
{
BOOL Ret = FALSE;
HBRUSH hBgBrush, hOldBrush = NULL;
RECTL Rect = *lpRc;
BOOL HasIcon;
RECTL_vMakeWellOrdered(lpRc);
/* Determine whether the icon needs to be displayed */
if (!hIcon && pWnd != NULL)
{
HasIcon = (uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP) &&
(pWnd->style & WS_SYSMENU) && !(pWnd->ExStyle & WS_EX_TOOLWINDOW);
}
else
HasIcon = (hIcon != NULL);
// Draw the caption background
if((uFlags & DC_GRADIENT) && !(uFlags & DC_INBUTTON))
{
static GRADIENT_RECT gcap = {0, 1};
TRIVERTEX Vertices[2];
COLORREF Colors[2];
Colors[0] = IntGetSysColor((uFlags & DC_ACTIVE) ?
COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION);
Colors[1] = IntGetSysColor((uFlags & DC_ACTIVE) ?
COLOR_GRADIENTACTIVECAPTION : COLOR_GRADIENTINACTIVECAPTION);
Vertices[0].x = Rect.left;
Vertices[0].y = Rect.top;
Vertices[0].Red = (WORD)Colors[0]<<8;
Vertices[0].Green = (WORD)Colors[0] & 0xFF00;
Vertices[0].Blue = (WORD)(Colors[0]>>8) & 0xFF00;
Vertices[0].Alpha = 0;
Vertices[1].x = Rect.right;
Vertices[1].y = Rect.bottom;
Vertices[1].Red = (WORD)Colors[1]<<8;
Vertices[1].Green = (WORD)Colors[1] & 0xFF00;
Vertices[1].Blue = (WORD)(Colors[1]>>8) & 0xFF00;
Vertices[1].Alpha = 0;
if(!GreGradientFill(hDc, Vertices, 2, &gcap, 1, GRADIENT_FILL_RECT_H))
{
ERR("GreGradientFill() failed!\n");
goto cleanup;
}
}
else
{
if(uFlags & DC_INBUTTON)
hBgBrush = IntGetSysColorBrush(COLOR_3DFACE);
else if(uFlags & DC_ACTIVE)
hBgBrush = IntGetSysColorBrush(COLOR_ACTIVECAPTION);
else
hBgBrush = IntGetSysColorBrush(COLOR_INACTIVECAPTION);
hOldBrush = NtGdiSelectBrush(hDc, hBgBrush);
if(!hOldBrush)
{
ERR("NtGdiSelectBrush() failed!\n");
goto cleanup;
}
if(!NtGdiPatBlt(hDc, Rect.left, Rect.top,
Rect.right - Rect.left,
Rect.bottom - Rect.top,
PATCOPY))
{
ERR("NtGdiPatBlt() failed!\n");
goto cleanup;
}
}
/* Draw icon */
if (HasIcon)
{
PCURICON_OBJECT pIcon = NULL;
if (hIcon)
{
pIcon = UserGetCurIconObject(hIcon);
}
else if (pWnd)
{
pIcon = NC_IconForWindow(pWnd);
// FIXME: NC_IconForWindow should reference it for us */
if (pIcon)
UserReferenceObject(pIcon);
}
if (pIcon)
{
LONG cx = UserGetSystemMetrics(SM_CXSMICON);
LONG cy = UserGetSystemMetrics(SM_CYSMICON);
LONG x = Rect.left - cx/2 + 1 + (Rect.bottom - Rect.top)/2; // this is really what Window does
LONG y = (Rect.top + Rect.bottom - cy)/2; // center
UserDrawIconEx(hDc, x, y, pIcon, cx, cy, 0, NULL, DI_NORMAL);
UserDereferenceObject(pIcon);
}
else
{
HasIcon = FALSE;
}
}
if (HasIcon)
Rect.left += Rect.bottom - Rect.top;
if((uFlags & DC_TEXT))
{
BOOL Set = FALSE;
Rect.left += 2;
if (Str)
Set = UserDrawCaptionText(pWnd, hDc, Str, &Rect, uFlags, hFont);
else if (pWnd != NULL) // FIXME: Windows does not do that
{
UNICODE_STRING ustr;
ustr.Buffer = pWnd->strName.Buffer; // FIXME: LARGE_STRING truncated!
ustr.Length = (USHORT)min(pWnd->strName.Length, MAXUSHORT);
ustr.MaximumLength = (USHORT)min(pWnd->strName.MaximumLength, MAXUSHORT);
Set = UserDrawCaptionText(pWnd, hDc, &ustr, &Rect, uFlags, hFont);
}
if (pWnd)
{
if (Set)
pWnd->state2 &= ~WNDS2_CAPTIONTEXTTRUNCATED;
else
pWnd->state2 |= WNDS2_CAPTIONTEXTTRUNCATED;
}
}
Ret = TRUE;
cleanup:
if (hOldBrush) NtGdiSelectBrush(hDc, hOldBrush);
return Ret;
}
INT
FASTCALL
UserRealizePalette(HDC hdc)
{
HWND hWnd, hWndDesktop;
DWORD Ret;
Ret = IntGdiRealizePalette(hdc);
if (Ret) // There was a change.
{
hWnd = IntWindowFromDC(hdc);
if (hWnd) // Send broadcast if dc is associated with a window.
{ // FYI: Thread locked in CallOneParam.
hWndDesktop = IntGetDesktopWindow();
if ( hWndDesktop != hWnd )
{
PWND pWnd = UserGetWindowObject(hWndDesktop);
ERR("RealizePalette Desktop.\n");
hdc = UserGetWindowDC(pWnd);
IntPaintDesktop(hdc);
UserReleaseDC(pWnd,hdc,FALSE);
}
UserSendNotifyMessage((HWND)HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hWnd, 0);
}
}
return Ret;
}
BOOL
APIENTRY
NtUserDrawCaptionTemp(
HWND hWnd,
HDC hDC,
LPCRECT lpRc,
HFONT hFont,
HICON hIcon,
const PUNICODE_STRING str,
UINT uFlags)
{
PWND pWnd = NULL;
UNICODE_STRING SafeStr = {0};
NTSTATUS Status = STATUS_SUCCESS;
RECTL SafeRect;
BOOL Ret;
UserEnterExclusive();
if (hWnd != NULL)
{
if(!(pWnd = UserGetWindowObject(hWnd)))
{
UserLeave();
return FALSE;
}
}
modified include/reactos/probe.h Workaround for gcc 4.1.3. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38054#c7 modified ntoskrnl/include/internal/mm.h gcc 4.3.2 doesn't like to be told to inline MmAcquirePageListLock modified ntoskrnl/include/internal/probe.h Cleaning up after TSVN's buggy "apply patch" modified subsystems/win32/win32k/ntuser/message.c Silence a gcc 4.3.2 warning (possibly incorrectly) modified dll/directx/ddraw/ddraw.rbuild modified dll/win32/gdi32/gdi32.rbuild modified dll/win32/kernel32/kernel32.rbuild modified dll/win32/psapi/psapi.rbuild modified dll/win32/setupapi/setupapi.rbuild modified dll/win32/syssetup/syssetup.rbuild modified dll/win32/user32/user32.rbuild modified drivers/input/kbdclass/kbdclass.rbuild modified drivers/input/mouclass/mouclass.rbuild modified drivers/network/afd/afd.rbuild modified drivers/network/tcpip/tcpip.rbuild modified lib/rtl/rtl.rbuild modified subsystems/win32/win32k/win32k.rbuild modified subsystems/win32/win32k/objects/gdiobj.c gcc 4.1.3 workarounds. See embedded comments modified base/services/eventlog/eventlog.h modified dll/win32/advapi32/advapi32.h Removed superfluous includes of pseh/pseh.h modified dll/directx/ddraw/Ddraw/ddraw_displaymode.c modified dll/directx/ddraw/Ddraw/ddraw_main.c modified dll/directx/ddraw/Ddraw/ddraw_setcooperativelevel.c modified dll/directx/ddraw/Ddraw/GetCaps.c modified dll/directx/ddraw/Ddraw/GetDeviceIdentifier.c modified dll/directx/ddraw/main.c modified dll/directx/ddraw/rosdraw.h modified dll/directx/ddraw/Surface/surface_main.c ddraw migrated to PSEH 2.0 modified dll/win32/gdi32/include/precomp.h modified dll/win32/gdi32/misc/misc.c modified dll/win32/gdi32/objects/bitmap.c gdi32 migrated to PSEH 2.0 modified dll/win32/kernel32/except/except.c modified dll/win32/kernel32/file/find.c modified dll/win32/kernel32/k32.h modified dll/win32/kernel32/mem/isbad.c modified dll/win32/kernel32/misc/console.c modified dll/win32/kernel32/process/procsup.c modified dll/win32/kernel32/string/lstring.c modified dll/win32/kernel32/thread/thread.c kernel32 migrated to PSEH 2.0 modified dll/win32/psapi/precomp.h modified dll/win32/psapi/psapi.c psapi migrated to PSEH 2.0 modified dll/win32/setupapi/cfgmgr.c modified dll/win32/setupapi/setupapi_private.h setupapi migrated to PSEH 2.0 modified dll/win32/syssetup/wizard.c syssetup migrated to PSEH 2.0 modified dll/win32/user32/include/user32.h modified dll/win32/user32/windows/class.c modified dll/win32/user32/windows/text.c modified dll/win32/user32/windows/window.c user32 migrated to PSEH 2.0 modified drivers/input/kbdclass/kbdclass.c modified drivers/input/kbdclass/kbdclass.h kbdclass migrated to PSEH 2.0 modified drivers/input/mouclass/mouclass.c modified drivers/input/mouclass/mouclass.h mouclass migrated to PSEH 2.0 modified drivers/network/afd/afd/info.c modified drivers/network/afd/afd/lock.c modified drivers/network/afd/afd/tdi.c modified drivers/network/afd/afd/tdiconn.c afd migrated to PSEH 2.0 modified drivers/network/lan/lan/lan.c lan migrated to PSEH 2.0 modified drivers/network/tcpip/tcpip/dispatch.c tcpip migrated to PSEH 2.0 modified lib/rtl/debug.c modified lib/rtl/res.c modified lib/rtl/rtl.h modified lib/rtl/unicode.c modified lib/rtl/workitem.c rtl migrated to PSEH 2.0 modified ntoskrnl/include/precomp.h ntoskrnl migrated to PSEH 2.0 modified subsystems/csr/csrsrv/api.c csrsrv migrated to PSEH 2.0 modified subsystems/win32/win32k/eng/bitblt.c modified subsystems/win32/win32k/eng/mem.c modified subsystems/win32/win32k/include/mmcopy.h modified subsystems/win32/win32k/misc/copy.c modified subsystems/win32/win32k/ntuser/callback.c modified subsystems/win32/win32k/ntuser/class.c modified subsystems/win32/win32k/ntuser/clipboard.c modified subsystems/win32/win32k/ntuser/cursoricon.c modified subsystems/win32/win32k/ntuser/display.c modified subsystems/win32/win32k/ntuser/hook.c modified subsystems/win32/win32k/ntuser/input.c modified subsystems/win32/win32k/ntuser/kbdlayout.c modified subsystems/win32/win32k/ntuser/menu.c modified subsystems/win32/win32k/ntuser/misc.c modified subsystems/win32/win32k/ntuser/ntstubs.c modified subsystems/win32/win32k/ntuser/painting.c modified subsystems/win32/win32k/ntuser/simplecall.c modified subsystems/win32/win32k/ntuser/sysparams.c modified subsystems/win32/win32k/ntuser/window.c modified subsystems/win32/win32k/objects/bitblt.c modified subsystems/win32/win32k/objects/bitmaps.c modified subsystems/win32/win32k/objects/brush.c modified subsystems/win32/win32k/objects/cliprgn.c modified subsystems/win32/win32k/objects/color.c modified subsystems/win32/win32k/objects/coord.c modified subsystems/win32/win32k/objects/dc.c modified subsystems/win32/win32k/objects/dcutil.c modified subsystems/win32/win32k/objects/dibobj.c modified subsystems/win32/win32k/objects/fillshap.c modified subsystems/win32/win32k/objects/font.c modified subsystems/win32/win32k/objects/freetype.c modified subsystems/win32/win32k/objects/icm.c modified subsystems/win32/win32k/objects/line.c modified subsystems/win32/win32k/objects/path.c modified subsystems/win32/win32k/objects/pen.c modified subsystems/win32/win32k/objects/print.c modified subsystems/win32/win32k/objects/region.c modified subsystems/win32/win32k/objects/text.c modified subsystems/win32/win32k/pch.h win32k migrated to PSEH 2.0 svn path=/trunk/; revision=37776
2008-11-30 19:28:11 +00:00
_SEH2_TRY
{
ProbeForRead(lpRc, sizeof(RECTL), sizeof(ULONG));
RtlCopyMemory(&SafeRect, lpRc, sizeof(RECTL));
if (str != NULL)
{
SafeStr = ProbeForReadUnicodeString(str);
if (SafeStr.Length != 0)
{
ProbeForRead( SafeStr.Buffer,
SafeStr.Length,
sizeof(WCHAR));
}
}
}
modified include/reactos/probe.h Workaround for gcc 4.1.3. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38054#c7 modified ntoskrnl/include/internal/mm.h gcc 4.3.2 doesn't like to be told to inline MmAcquirePageListLock modified ntoskrnl/include/internal/probe.h Cleaning up after TSVN's buggy "apply patch" modified subsystems/win32/win32k/ntuser/message.c Silence a gcc 4.3.2 warning (possibly incorrectly) modified dll/directx/ddraw/ddraw.rbuild modified dll/win32/gdi32/gdi32.rbuild modified dll/win32/kernel32/kernel32.rbuild modified dll/win32/psapi/psapi.rbuild modified dll/win32/setupapi/setupapi.rbuild modified dll/win32/syssetup/syssetup.rbuild modified dll/win32/user32/user32.rbuild modified drivers/input/kbdclass/kbdclass.rbuild modified drivers/input/mouclass/mouclass.rbuild modified drivers/network/afd/afd.rbuild modified drivers/network/tcpip/tcpip.rbuild modified lib/rtl/rtl.rbuild modified subsystems/win32/win32k/win32k.rbuild modified subsystems/win32/win32k/objects/gdiobj.c gcc 4.1.3 workarounds. See embedded comments modified base/services/eventlog/eventlog.h modified dll/win32/advapi32/advapi32.h Removed superfluous includes of pseh/pseh.h modified dll/directx/ddraw/Ddraw/ddraw_displaymode.c modified dll/directx/ddraw/Ddraw/ddraw_main.c modified dll/directx/ddraw/Ddraw/ddraw_setcooperativelevel.c modified dll/directx/ddraw/Ddraw/GetCaps.c modified dll/directx/ddraw/Ddraw/GetDeviceIdentifier.c modified dll/directx/ddraw/main.c modified dll/directx/ddraw/rosdraw.h modified dll/directx/ddraw/Surface/surface_main.c ddraw migrated to PSEH 2.0 modified dll/win32/gdi32/include/precomp.h modified dll/win32/gdi32/misc/misc.c modified dll/win32/gdi32/objects/bitmap.c gdi32 migrated to PSEH 2.0 modified dll/win32/kernel32/except/except.c modified dll/win32/kernel32/file/find.c modified dll/win32/kernel32/k32.h modified dll/win32/kernel32/mem/isbad.c modified dll/win32/kernel32/misc/console.c modified dll/win32/kernel32/process/procsup.c modified dll/win32/kernel32/string/lstring.c modified dll/win32/kernel32/thread/thread.c kernel32 migrated to PSEH 2.0 modified dll/win32/psapi/precomp.h modified dll/win32/psapi/psapi.c psapi migrated to PSEH 2.0 modified dll/win32/setupapi/cfgmgr.c modified dll/win32/setupapi/setupapi_private.h setupapi migrated to PSEH 2.0 modified dll/win32/syssetup/wizard.c syssetup migrated to PSEH 2.0 modified dll/win32/user32/include/user32.h modified dll/win32/user32/windows/class.c modified dll/win32/user32/windows/text.c modified dll/win32/user32/windows/window.c user32 migrated to PSEH 2.0 modified drivers/input/kbdclass/kbdclass.c modified drivers/input/kbdclass/kbdclass.h kbdclass migrated to PSEH 2.0 modified drivers/input/mouclass/mouclass.c modified drivers/input/mouclass/mouclass.h mouclass migrated to PSEH 2.0 modified drivers/network/afd/afd/info.c modified drivers/network/afd/afd/lock.c modified drivers/network/afd/afd/tdi.c modified drivers/network/afd/afd/tdiconn.c afd migrated to PSEH 2.0 modified drivers/network/lan/lan/lan.c lan migrated to PSEH 2.0 modified drivers/network/tcpip/tcpip/dispatch.c tcpip migrated to PSEH 2.0 modified lib/rtl/debug.c modified lib/rtl/res.c modified lib/rtl/rtl.h modified lib/rtl/unicode.c modified lib/rtl/workitem.c rtl migrated to PSEH 2.0 modified ntoskrnl/include/precomp.h ntoskrnl migrated to PSEH 2.0 modified subsystems/csr/csrsrv/api.c csrsrv migrated to PSEH 2.0 modified subsystems/win32/win32k/eng/bitblt.c modified subsystems/win32/win32k/eng/mem.c modified subsystems/win32/win32k/include/mmcopy.h modified subsystems/win32/win32k/misc/copy.c modified subsystems/win32/win32k/ntuser/callback.c modified subsystems/win32/win32k/ntuser/class.c modified subsystems/win32/win32k/ntuser/clipboard.c modified subsystems/win32/win32k/ntuser/cursoricon.c modified subsystems/win32/win32k/ntuser/display.c modified subsystems/win32/win32k/ntuser/hook.c modified subsystems/win32/win32k/ntuser/input.c modified subsystems/win32/win32k/ntuser/kbdlayout.c modified subsystems/win32/win32k/ntuser/menu.c modified subsystems/win32/win32k/ntuser/misc.c modified subsystems/win32/win32k/ntuser/ntstubs.c modified subsystems/win32/win32k/ntuser/painting.c modified subsystems/win32/win32k/ntuser/simplecall.c modified subsystems/win32/win32k/ntuser/sysparams.c modified subsystems/win32/win32k/ntuser/window.c modified subsystems/win32/win32k/objects/bitblt.c modified subsystems/win32/win32k/objects/bitmaps.c modified subsystems/win32/win32k/objects/brush.c modified subsystems/win32/win32k/objects/cliprgn.c modified subsystems/win32/win32k/objects/color.c modified subsystems/win32/win32k/objects/coord.c modified subsystems/win32/win32k/objects/dc.c modified subsystems/win32/win32k/objects/dcutil.c modified subsystems/win32/win32k/objects/dibobj.c modified subsystems/win32/win32k/objects/fillshap.c modified subsystems/win32/win32k/objects/font.c modified subsystems/win32/win32k/objects/freetype.c modified subsystems/win32/win32k/objects/icm.c modified subsystems/win32/win32k/objects/line.c modified subsystems/win32/win32k/objects/path.c modified subsystems/win32/win32k/objects/pen.c modified subsystems/win32/win32k/objects/print.c modified subsystems/win32/win32k/objects/region.c modified subsystems/win32/win32k/objects/text.c modified subsystems/win32/win32k/pch.h win32k migrated to PSEH 2.0 svn path=/trunk/; revision=37776
2008-11-30 19:28:11 +00:00
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
modified include/reactos/probe.h Workaround for gcc 4.1.3. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38054#c7 modified ntoskrnl/include/internal/mm.h gcc 4.3.2 doesn't like to be told to inline MmAcquirePageListLock modified ntoskrnl/include/internal/probe.h Cleaning up after TSVN's buggy "apply patch" modified subsystems/win32/win32k/ntuser/message.c Silence a gcc 4.3.2 warning (possibly incorrectly) modified dll/directx/ddraw/ddraw.rbuild modified dll/win32/gdi32/gdi32.rbuild modified dll/win32/kernel32/kernel32.rbuild modified dll/win32/psapi/psapi.rbuild modified dll/win32/setupapi/setupapi.rbuild modified dll/win32/syssetup/syssetup.rbuild modified dll/win32/user32/user32.rbuild modified drivers/input/kbdclass/kbdclass.rbuild modified drivers/input/mouclass/mouclass.rbuild modified drivers/network/afd/afd.rbuild modified drivers/network/tcpip/tcpip.rbuild modified lib/rtl/rtl.rbuild modified subsystems/win32/win32k/win32k.rbuild modified subsystems/win32/win32k/objects/gdiobj.c gcc 4.1.3 workarounds. See embedded comments modified base/services/eventlog/eventlog.h modified dll/win32/advapi32/advapi32.h Removed superfluous includes of pseh/pseh.h modified dll/directx/ddraw/Ddraw/ddraw_displaymode.c modified dll/directx/ddraw/Ddraw/ddraw_main.c modified dll/directx/ddraw/Ddraw/ddraw_setcooperativelevel.c modified dll/directx/ddraw/Ddraw/GetCaps.c modified dll/directx/ddraw/Ddraw/GetDeviceIdentifier.c modified dll/directx/ddraw/main.c modified dll/directx/ddraw/rosdraw.h modified dll/directx/ddraw/Surface/surface_main.c ddraw migrated to PSEH 2.0 modified dll/win32/gdi32/include/precomp.h modified dll/win32/gdi32/misc/misc.c modified dll/win32/gdi32/objects/bitmap.c gdi32 migrated to PSEH 2.0 modified dll/win32/kernel32/except/except.c modified dll/win32/kernel32/file/find.c modified dll/win32/kernel32/k32.h modified dll/win32/kernel32/mem/isbad.c modified dll/win32/kernel32/misc/console.c modified dll/win32/kernel32/process/procsup.c modified dll/win32/kernel32/string/lstring.c modified dll/win32/kernel32/thread/thread.c kernel32 migrated to PSEH 2.0 modified dll/win32/psapi/precomp.h modified dll/win32/psapi/psapi.c psapi migrated to PSEH 2.0 modified dll/win32/setupapi/cfgmgr.c modified dll/win32/setupapi/setupapi_private.h setupapi migrated to PSEH 2.0 modified dll/win32/syssetup/wizard.c syssetup migrated to PSEH 2.0 modified dll/win32/user32/include/user32.h modified dll/win32/user32/windows/class.c modified dll/win32/user32/windows/text.c modified dll/win32/user32/windows/window.c user32 migrated to PSEH 2.0 modified drivers/input/kbdclass/kbdclass.c modified drivers/input/kbdclass/kbdclass.h kbdclass migrated to PSEH 2.0 modified drivers/input/mouclass/mouclass.c modified drivers/input/mouclass/mouclass.h mouclass migrated to PSEH 2.0 modified drivers/network/afd/afd/info.c modified drivers/network/afd/afd/lock.c modified drivers/network/afd/afd/tdi.c modified drivers/network/afd/afd/tdiconn.c afd migrated to PSEH 2.0 modified drivers/network/lan/lan/lan.c lan migrated to PSEH 2.0 modified drivers/network/tcpip/tcpip/dispatch.c tcpip migrated to PSEH 2.0 modified lib/rtl/debug.c modified lib/rtl/res.c modified lib/rtl/rtl.h modified lib/rtl/unicode.c modified lib/rtl/workitem.c rtl migrated to PSEH 2.0 modified ntoskrnl/include/precomp.h ntoskrnl migrated to PSEH 2.0 modified subsystems/csr/csrsrv/api.c csrsrv migrated to PSEH 2.0 modified subsystems/win32/win32k/eng/bitblt.c modified subsystems/win32/win32k/eng/mem.c modified subsystems/win32/win32k/include/mmcopy.h modified subsystems/win32/win32k/misc/copy.c modified subsystems/win32/win32k/ntuser/callback.c modified subsystems/win32/win32k/ntuser/class.c modified subsystems/win32/win32k/ntuser/clipboard.c modified subsystems/win32/win32k/ntuser/cursoricon.c modified subsystems/win32/win32k/ntuser/display.c modified subsystems/win32/win32k/ntuser/hook.c modified subsystems/win32/win32k/ntuser/input.c modified subsystems/win32/win32k/ntuser/kbdlayout.c modified subsystems/win32/win32k/ntuser/menu.c modified subsystems/win32/win32k/ntuser/misc.c modified subsystems/win32/win32k/ntuser/ntstubs.c modified subsystems/win32/win32k/ntuser/painting.c modified subsystems/win32/win32k/ntuser/simplecall.c modified subsystems/win32/win32k/ntuser/sysparams.c modified subsystems/win32/win32k/ntuser/window.c modified subsystems/win32/win32k/objects/bitblt.c modified subsystems/win32/win32k/objects/bitmaps.c modified subsystems/win32/win32k/objects/brush.c modified subsystems/win32/win32k/objects/cliprgn.c modified subsystems/win32/win32k/objects/color.c modified subsystems/win32/win32k/objects/coord.c modified subsystems/win32/win32k/objects/dc.c modified subsystems/win32/win32k/objects/dcutil.c modified subsystems/win32/win32k/objects/dibobj.c modified subsystems/win32/win32k/objects/fillshap.c modified subsystems/win32/win32k/objects/font.c modified subsystems/win32/win32k/objects/freetype.c modified subsystems/win32/win32k/objects/icm.c modified subsystems/win32/win32k/objects/line.c modified subsystems/win32/win32k/objects/path.c modified subsystems/win32/win32k/objects/pen.c modified subsystems/win32/win32k/objects/print.c modified subsystems/win32/win32k/objects/region.c modified subsystems/win32/win32k/objects/text.c modified subsystems/win32/win32k/pch.h win32k migrated to PSEH 2.0 svn path=/trunk/; revision=37776
2008-11-30 19:28:11 +00:00
_SEH2_END;
if (Status != STATUS_SUCCESS)
{
SetLastNtError(Status);
UserLeave();
return FALSE;
}
if (str != NULL)
Ret = UserDrawCaption(pWnd, hDC, &SafeRect, hFont, hIcon, &SafeStr, uFlags);
else
{
if ( RECTL_bIsEmptyRect(&SafeRect) && hFont == 0 && hIcon == 0 )
{
Ret = TRUE;
if (uFlags & DC_DRAWCAPTIONMD)
{
ERR("NC Caption Mode\n");
UserDrawCaptionBar(pWnd, hDC, uFlags);
goto Exit;
}
else if (uFlags & DC_DRAWFRAMEMD)
{
ERR("NC Paint Mode\n");
NC_DoNCPaint(pWnd, hDC, uFlags); // Update Menus too!
goto Exit;
}
}
Ret = UserDrawCaption(pWnd, hDC, &SafeRect, hFont, hIcon, NULL, uFlags);
}
Exit:
UserLeave();
return Ret;
}
BOOL
APIENTRY
NtUserDrawCaption(HWND hWnd,
HDC hDC,
LPCRECT lpRc,
UINT uFlags)
{
return NtUserDrawCaptionTemp(hWnd, hDC, lpRc, 0, 0, NULL, uFlags);
}
INT FASTCALL
co_UserExcludeUpdateRgn(HDC hDC, PWND Window)
{
POINT pt;
RECT rc;
if (Window->hrgnUpdate)
{
if (Window->hrgnUpdate == HRGN_WINDOW)
{
return NtGdiIntersectClipRect(hDC, 0, 0, 0, 0);
}
else
{
INT ret = ERROR;
HRGN hrgn = NtGdiCreateRectRgn(0,0,0,0);
if ( hrgn && GreGetDCPoint( hDC, GdiGetDCOrg, &pt) )
{
if ( NtGdiGetRandomRgn( hDC, hrgn, CLIPRGN) == NULLREGION )
{
NtGdiOffsetRgn(hrgn, pt.x, pt.y);
}
else
{
HRGN hrgnScreen;
PMONITOR pm = UserGetPrimaryMonitor();
hrgnScreen = NtGdiCreateRectRgn(0,0,0,0);
NtGdiCombineRgn(hrgnScreen, hrgnScreen, pm->hrgnMonitor, RGN_OR);
NtGdiCombineRgn(hrgn, hrgnScreen, NULL, RGN_COPY);
GreDeleteObject(hrgnScreen);
}
NtGdiCombineRgn(hrgn, hrgn, Window->hrgnUpdate, RGN_DIFF);
NtGdiOffsetRgn(hrgn, -pt.x, -pt.y);
ret = NtGdiExtSelectClipRgn(hDC, hrgn, RGN_COPY);
GreDeleteObject(hrgn);
}
return ret;
}
}
else
{
return GdiGetClipBox( hDC, &rc);
}
}
INT
APIENTRY
NtUserExcludeUpdateRgn(
HDC hDC,
HWND hWnd)
{
INT ret = ERROR;
PWND pWnd;
TRACE("Enter NtUserExcludeUpdateRgn\n");
UserEnterExclusive();
pWnd = UserGetWindowObject(hWnd);
if (hDC && pWnd)
ret = co_UserExcludeUpdateRgn(hDC, pWnd);
TRACE("Leave NtUserExcludeUpdateRgn, ret=%i\n", ret);
UserLeave();
return ret;
}
BOOL
APIENTRY
NtUserInvalidateRect(
HWND hWnd,
CONST RECT *lpUnsafeRect,
BOOL bErase)
{
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
APIENTRY
NtUserInvalidateRgn(
HWND hWnd,
HRGN hRgn,
BOOL bErase)
{
if (!hWnd)
{
EngSetLastError( ERROR_INVALID_WINDOW_HANDLE );
return FALSE;
}
return NtUserRedrawWindow(hWnd, NULL, hRgn, RDW_INVALIDATE | (bErase? RDW_ERASE : 0));
}
BOOL
APIENTRY
NtUserPrintWindow(
HWND hwnd,
HDC hdcBlt,
UINT nFlags)
{
PWND Window;
BOOL Ret = FALSE;
UserEnterExclusive();
if (hwnd)
{
if (!(Window = UserGetWindowObject(hwnd)) ||
UserIsDesktopWindow(Window) || UserIsMessageWindow(Window))
{
goto Exit;
}
if ( Window )
{
/* Validate flags and check it as a mask for 0 or 1. */
if ( (nFlags & PW_CLIENTONLY) == nFlags)
Ret = IntPrintWindow( Window, hdcBlt, nFlags);
else
EngSetLastError(ERROR_INVALID_PARAMETER);
}
}
Exit:
UserLeave();
return Ret;
}
/* ValidateRect gets redirected to NtUserValidateRect:
http://blog.csdn.net/ntdll/archive/2005/10/19/509299.aspx */
BOOL
APIENTRY
NtUserValidateRect(
HWND hWnd,
const RECT *lpRect)
{
UINT flags = RDW_VALIDATE;
if (!hWnd)
{
flags = RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW;
lpRect = NULL;
}
return NtUserRedrawWindow(hWnd, lpRect, NULL, flags);
}
/* EOF */