From 1ccabd4c8ee9112958e333979fa2643f128bf900 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Tue, 18 Nov 2003 20:49:39 +0000 Subject: [PATCH] - Rewritten painting implementation (not complete yet, but better then the current). - Bug fixes. svn path=/trunk/; revision=6691 --- reactos/include/win32k/ntuser.h | 9 +- reactos/lib/user32/windows/nonclient.c | 7 - reactos/subsys/win32k/eng/bitblt.c | 3 +- reactos/subsys/win32k/include/callback.h | 8 +- reactos/subsys/win32k/include/caret.h | 6 +- reactos/subsys/win32k/include/class.h | 6 +- reactos/subsys/win32k/include/color.h | 5 + reactos/subsys/win32k/include/dce.h | 6 +- reactos/subsys/win32k/include/dib.h | 6 +- reactos/subsys/win32k/include/eng.h | 6 +- reactos/subsys/win32k/include/error.h | 6 +- reactos/subsys/win32k/include/guicheck.h | 6 +- reactos/subsys/win32k/include/hotkey.h | 6 +- reactos/subsys/win32k/include/input.h | 6 +- reactos/subsys/win32k/include/inteng.h | 6 +- reactos/subsys/win32k/include/menu.h | 8 +- reactos/subsys/win32k/include/mouse.h | 6 +- reactos/subsys/win32k/include/msgqueue.h | 6 +- reactos/subsys/win32k/include/object.h | 6 +- reactos/subsys/win32k/include/paint.h | 6 +- reactos/subsys/win32k/include/painting.h | 34 +- reactos/subsys/win32k/include/palette.h | 6 +- reactos/subsys/win32k/include/path.h | 5 + reactos/subsys/win32k/include/prop.h | 2 - reactos/subsys/win32k/include/rect.h | 5 + reactos/subsys/win32k/include/scroll.h | 5 + reactos/subsys/win32k/include/surface.h | 6 +- reactos/subsys/win32k/include/text.h | 5 + reactos/subsys/win32k/include/timer.h | 6 +- reactos/subsys/win32k/include/window.h | 27 +- reactos/subsys/win32k/include/winpos.h | 5 + reactos/subsys/win32k/include/winsta.h | 6 +- reactos/subsys/win32k/ntuser/message.c | 39 +- reactos/subsys/win32k/ntuser/painting.c | 1641 ++++++++++------------ reactos/subsys/win32k/ntuser/stubs.c | 14 +- reactos/subsys/win32k/ntuser/vis.c | 19 +- reactos/subsys/win32k/ntuser/windc.c | 16 +- reactos/subsys/win32k/ntuser/window.c | 172 +-- reactos/subsys/win32k/ntuser/winpos.c | 115 +- reactos/subsys/win32k/objects/region.c | 29 +- 40 files changed, 995 insertions(+), 1286 deletions(-) diff --git a/reactos/include/win32k/ntuser.h b/reactos/include/win32k/ntuser.h index 1f5d6078141..561d075ebda 100644 --- a/reactos/include/win32k/ntuser.h +++ b/reactos/include/win32k/ntuser.h @@ -10,7 +10,6 @@ NtUserGetClassLong(HWND hWnd, DWORD Offset, BOOL Ansi); LONG STDCALL NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi); - INT STDCALL NtUserReleaseDC(HWND hWnd, HDC hDc); @@ -861,12 +860,8 @@ NtUserGetTitleBarInfo( DWORD Unknown0, DWORD Unknown1); -DWORD -STDCALL -NtUserGetUpdateRect( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2); +BOOL STDCALL +NtUserGetUpdateRect(HWND hWnd, LPRECT lpRect, BOOL fErase); int STDCALL diff --git a/reactos/lib/user32/windows/nonclient.c b/reactos/lib/user32/windows/nonclient.c index fc66397380a..3ed12f80083 100644 --- a/reactos/lib/user32/windows/nonclient.c +++ b/reactos/lib/user32/windows/nonclient.c @@ -323,14 +323,7 @@ DefWndNCPaint(HWND hWnd, HRGN hRgn) return 0; } -/* FIXME: This works on Windows, but not on ReactOS! */ -#ifdef __REACTOS__ - hDC = GetDCEx(hWnd, (hRgn > (HRGN)1) ? hRgn : 0, - /*DCX_USESTYLE*/0x10000 | DCX_WINDOW | - ((hRgn > (HRGN)1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0)); -#else hDC = GetDCEx(hWnd, hRgn, DCX_WINDOW | DCX_INTERSECTRGN | 0x10000); -#endif if (hDC == 0) { return 0; diff --git a/reactos/subsys/win32k/eng/bitblt.c b/reactos/subsys/win32k/eng/bitblt.c index 317b11e7dd2..f9dc4ba0378 100644 --- a/reactos/subsys/win32k/eng/bitblt.c +++ b/reactos/subsys/win32k/eng/bitblt.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: bitblt.c,v 1.28 2003/10/29 08:38:55 gvg Exp $ +/* $Id: bitblt.c,v 1.29 2003/11/18 20:49:39 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -40,7 +40,6 @@ #include #include #include -#include #include //#define NDEBUG diff --git a/reactos/subsys/win32k/include/callback.h b/reactos/subsys/win32k/include/callback.h index d2e52740143..8a47f032617 100644 --- a/reactos/subsys/win32k/include/callback.h +++ b/reactos/subsys/win32k/include/callback.h @@ -1,5 +1,5 @@ -#ifndef __SUBSYS_WIN32K_INCLUDE_CALLBACK_H -#define __SUBSYS_WIN32K_INCLUDE_CALLBACK_H +#ifndef _WIN32K_CALLBACK_H +#define _WIN32K_CALLBACK_H LRESULT STDCALL IntCallWindowProc(WNDPROC Proc, @@ -23,9 +23,11 @@ IntCallSentMessageCallback(SENDASYNCPROC CompletionCallback, UINT Msg, ULONG_PTR CompletionCallbackContext, LRESULT Result); + LRESULT STDCALL IntSendNCCALCSIZEMessage(HWND Wnd, BOOL Validate, PRECT Rect, NCCALCSIZE_PARAMS* Params); + LRESULT STDCALL IntSendGETMINMAXINFOMessage(HWND Wnd, MINMAXINFO* MinMaxInfo); @@ -47,4 +49,4 @@ IntLoadSysMenuTemplate(); BOOL STDCALL IntLoadDefaultCursors(); -#endif /* __SUBSYS_WIN32K_INCLUDE_CALLBACK_H */ +#endif /* _WIN32K_CALLBACK_H */ diff --git a/reactos/subsys/win32k/include/caret.h b/reactos/subsys/win32k/include/caret.h index 0fac7387d18..13d9904d913 100644 --- a/reactos/subsys/win32k/include/caret.h +++ b/reactos/subsys/win32k/include/caret.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_CARET_H -#define __WIN32K_CARET_H +#ifndef _WIN32K_CARET_H +#define _WIN32K_CARET_H #include #include @@ -33,6 +33,6 @@ IntSwitchCaretShowing(PVOID Info); VOID FASTCALL IntDrawCaret(HWND hWnd); -#endif /* __WIN32K_CARET_H */ +#endif /* _WIN32K_CARET_H */ /* EOF */ diff --git a/reactos/subsys/win32k/include/class.h b/reactos/subsys/win32k/include/class.h index 3accd588983..d67994854ea 100644 --- a/reactos/subsys/win32k/include/class.h +++ b/reactos/subsys/win32k/include/class.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_CLASS_H -#define __WIN32K_CLASS_H +#ifndef _WIN32K_CLASS_H +#define _WIN32K_CLASS_H #include #include @@ -54,6 +54,6 @@ struct _WINDOW_OBJECT; ULONG FASTCALL IntGetClassLong(struct _WINDOW_OBJECT *WindowObject, ULONG Offset, BOOL Ansi); -#endif /* __WIN32K_CLASS_H */ +#endif /* _WIN32K_CLASS_H */ /* EOF */ diff --git a/reactos/subsys/win32k/include/color.h b/reactos/subsys/win32k/include/color.h index 8e756637f60..5aaed89a0bd 100644 --- a/reactos/subsys/win32k/include/color.h +++ b/reactos/subsys/win32k/include/color.h @@ -1,6 +1,11 @@ +#ifndef _WIN32K_COLOR_H +#define _WIN32K_COLOR_H + const PALETTEENTRY* FASTCALL COLOR_GetSystemPaletteTemplate (VOID); COLORREF STDCALL COLOR_LookupNearestColor (PALETTEENTRY* palPalEntry, INT size, COLORREF color); INT STDCALL COLOR_PaletteLookupExactIndex (PALETTEENTRY* palPalEntry, INT size, COLORREF col); INT STDCALL COLOR_PaletteLookupPixel(PALETTEENTRY *palPalEntry, INT size, PXLATEOBJ XlateObj, COLORREF col, BOOL skipReserved); ULONG FASTCALL NtGdiGetSysColor(int nIndex); HBRUSH STDCALL NtGdiGetSysColorBrush(int nIndex); + +#endif /* _WIN32K_COLOR_H */ diff --git a/reactos/subsys/win32k/include/dce.h b/reactos/subsys/win32k/include/dce.h index 0bd81c2ccb9..390f1404a0d 100644 --- a/reactos/subsys/win32k/include/dce.h +++ b/reactos/subsys/win32k/include/dce.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_DCE_H -#define __WIN32K_DCE_H +#ifndef _WIN32K_DCE_H +#define _WIN32K_DCE_H /* Ported from WINE by Jason Filby */ @@ -54,4 +54,4 @@ HWND FASTCALL IntWindowFromDC(HDC hDc); PDCE FASTCALL DceFreeDCE(PDCE dce); void FASTCALL DceFreeWindowDCE(PWINDOW_OBJECT Window); -#endif +#endif /* _WIN32K_DCE_H */ diff --git a/reactos/subsys/win32k/include/dib.h b/reactos/subsys/win32k/include/dib.h index d3c83bb2ac5..403d1e1673b 100644 --- a/reactos/subsys/win32k/include/dib.h +++ b/reactos/subsys/win32k/include/dib.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_DIB_H -#define __WIN32K_DIB_H +#ifndef _WIN32K_DIB_H +#define _WIN32K_DIB_H #include @@ -21,4 +21,4 @@ DIBColorTableToPaletteEntries(PPALETTEENTRY palEntries, const RGBQUAD *DIBColorT HPALETTE FASTCALL BuildDIBPalette (PBITMAPINFO bmi, PINT paletteType); -#endif /* __WIN32K_DIB_H */ +#endif /* _WIN32K_DIB_H */ diff --git a/reactos/subsys/win32k/include/eng.h b/reactos/subsys/win32k/include/eng.h index 5daaa706d02..9a94dd2b2bb 100644 --- a/reactos/subsys/win32k/include/eng.h +++ b/reactos/subsys/win32k/include/eng.h @@ -1,7 +1,7 @@ -#ifndef __WIN32K_ENG_H -#define __WIN32K_ENG_H +#ifndef _WIN32K_ENG_H +#define _WIN32K_ENG_H BOOL STDCALL EngIntersectRect (PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2); VOID FASTCALL EngDeleteXlate (XLATEOBJ *XlateObj); -#endif /* __WIN32K_ENG_H */ +#endif /* _WIN32K_ENG_H */ diff --git a/reactos/subsys/win32k/include/error.h b/reactos/subsys/win32k/include/error.h index f95762e686d..cf637b4c2ef 100644 --- a/reactos/subsys/win32k/include/error.h +++ b/reactos/subsys/win32k/include/error.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_ERROR_H -#define __WIN32K_ERROR_H +#ifndef _WIN32K_ERROR_H +#define _WIN32K_ERROR_H VOID FASTCALL SetLastNtError( @@ -12,6 +12,6 @@ SetLastWin32Error( NTSTATUS FASTCALL GetLastNtError(); -#endif /* __WIN32K_ERROR_H */ +#endif /* _WIN32K_ERROR_H */ /* EOF */ diff --git a/reactos/subsys/win32k/include/guicheck.h b/reactos/subsys/win32k/include/guicheck.h index 0c01b38cdad..fd51ba429cf 100644 --- a/reactos/subsys/win32k/include/guicheck.h +++ b/reactos/subsys/win32k/include/guicheck.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_GUICHECK_H -#define __WIN32K_GUICHECK_H +#ifndef _WIN32K_GUICHECK_H +#define _WIN32K_GUICHECK_H #include #include @@ -7,6 +7,6 @@ VOID FASTCALL IntGraphicsCheck(BOOL Create); -#endif /* __WIN32K_GUICHECK_H */ +#endif /* _WIN32K_GUICHECK_H */ /* EOF */ diff --git a/reactos/subsys/win32k/include/hotkey.h b/reactos/subsys/win32k/include/hotkey.h index 32c1f08ed49..449c4434bd3 100644 --- a/reactos/subsys/win32k/include/hotkey.h +++ b/reactos/subsys/win32k/include/hotkey.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_HOTKEY_H -#define __WIN32K_HOTKEY_H +#ifndef _WIN32K_HOTKEY_H +#define _WIN32K_HOTKEY_H #include #include @@ -36,6 +36,6 @@ UnregisterWindowHotKeys(PWINDOW_OBJECT Window); VOID UnregisterThreadHotKeys(struct _ETHREAD *Thread); -#endif /* __WIN32K_HOTKEY_H */ +#endif /* _WIN32K_HOTKEY_H */ /* EOF */ diff --git a/reactos/subsys/win32k/include/input.h b/reactos/subsys/win32k/include/input.h index 056f65b97d2..570b71ca67d 100644 --- a/reactos/subsys/win32k/include/input.h +++ b/reactos/subsys/win32k/include/input.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_INPUT_H -#define __WIN32K_INPUT_H +#ifndef _WIN32K_INPUT_H +#define _WIN32K_INPUT_H #include @@ -9,4 +9,4 @@ PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue(VOID); PKBDTABLES W32kGetDefaultKeyLayout(VOID); VOID FASTCALL W32kKeyProcessMessage(LPMSG Msg, PKBDTABLES KeyLayout); -#endif /* __WIN32K_INPUT_H */ +#endif /* _WIN32K_INPUT_H */ diff --git a/reactos/subsys/win32k/include/inteng.h b/reactos/subsys/win32k/include/inteng.h index aea4597adf4..1195f277308 100644 --- a/reactos/subsys/win32k/include/inteng.h +++ b/reactos/subsys/win32k/include/inteng.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_INTENG_H -#define __WIN32K_INTENG_H +#ifndef _WIN32K_INTENG_H +#define _WIN32K_INTENG_H /* Definitions of IntEngXxx functions */ @@ -38,4 +38,4 @@ BOOL STDCALL IntEngPolyline(SURFOBJ *DestSurf, CLIPOBJ* STDCALL IntEngCreateClipRegion(ULONG count, PRECTL pRect, RECTL rcBounds); -#endif +#endif /* _WIN32K_INTENG_H */ diff --git a/reactos/subsys/win32k/include/menu.h b/reactos/subsys/win32k/include/menu.h index a0c39beef15..d1e3c56f9da 100644 --- a/reactos/subsys/win32k/include/menu.h +++ b/reactos/subsys/win32k/include/menu.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_MENU_H -#define __WIN32K_MENU_H +#ifndef _WIN32K_MENU_H +#define _WIN32K_MENU_H #include #include @@ -285,6 +285,4 @@ NtUserTrackPopupMenuEx( HWND hwnd, LPTPMPARAMS lptpm); -#endif /* __WIN32K_MENU_H */ - -/* EOF */ +#endif /* _WIN32K_MENU_H */ diff --git a/reactos/subsys/win32k/include/mouse.h b/reactos/subsys/win32k/include/mouse.h index 98bb9c097cd..30ce73fcb82 100644 --- a/reactos/subsys/win32k/include/mouse.h +++ b/reactos/subsys/win32k/include/mouse.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_MOUSE_H -#define __WIN32K_MOUSE_H +#ifndef _WIN32K_MOUSE_H +#define _WIN32K_MOUSE_H #include "../eng/misc.h" #include @@ -14,4 +14,4 @@ VOID FASTCALL EnableMouse(HDC hDisplayDC); VOID MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount); -#endif /* __WIN32K_MOUSE_H */ +#endif /* _WIN32K_MOUSE_H */ diff --git a/reactos/subsys/win32k/include/msgqueue.h b/reactos/subsys/win32k/include/msgqueue.h index 0e27f397bb5..d96d8b1245e 100644 --- a/reactos/subsys/win32k/include/msgqueue.h +++ b/reactos/subsys/win32k/include/msgqueue.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_MSGQUEUE_H -#define __WIN32K_MSGQUEUE_H +#ifndef _WIN32K_MSGQUEUE_H +#define _WIN32K_MSGQUEUE_H #include @@ -138,6 +138,6 @@ inline VOID MsqClearQueueBits( PUSER_MESSAGE_QUEUE queue, WORD bits ); #define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF)) -#endif /* __WIN32K_MSGQUEUE_H */ +#endif /* _WIN32K_MSGQUEUE_H */ /* EOF */ diff --git a/reactos/subsys/win32k/include/object.h b/reactos/subsys/win32k/include/object.h index 39ec620422a..cf1d58bcd8f 100644 --- a/reactos/subsys/win32k/include/object.h +++ b/reactos/subsys/win32k/include/object.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_OBJECT_H -#define __WIN32K_OBJECT_H +#ifndef _WIN32K_OBJECT_H +#define _WIN32K_OBJECT_H #include #include @@ -139,6 +139,6 @@ HBITMAP FASTCALL BitmapToSurf ( PBITMAPOBJ BitmapObj ); -#endif /* __WIN32K_OBJECT_H */ +#endif /* _WIN32K_OBJECT_H */ /* EOF */ diff --git a/reactos/subsys/win32k/include/paint.h b/reactos/subsys/win32k/include/paint.h index dd187ba52a2..4f10180407c 100644 --- a/reactos/subsys/win32k/include/paint.h +++ b/reactos/subsys/win32k/include/paint.h @@ -1,7 +1,7 @@ -#ifndef __WIN32K_PAINT_H -#define __WIN32K_PAINT_H +#ifndef _WIN32K_PAINT_H +#define _WIN32K_PAINT_H BOOL STDCALL FillSolid (SURFOBJ* Surface, RECTL* Dimensions, ULONG iColor); BOOL STDCALL FillPolygon ( DC* dc, SURFOBJ* SurfObj, BRUSHOBJ* BrushObj, MIX RopMode, CONST PPOINT Points, INT Count, RECTL BoundRect ); -#endif /* __WIN32K_PAINT_H */ +#endif /* _WIN32K_PAINT_H */ diff --git a/reactos/subsys/win32k/include/painting.h b/reactos/subsys/win32k/include/painting.h index fa5196c0161..5caabcf9213 100644 --- a/reactos/subsys/win32k/include/painting.h +++ b/reactos/subsys/win32k/include/painting.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_PAINTING_H -#define __WIN32K_PAINTING_H +#ifndef _WIN32K_PAINTING_H +#define _WIN32K_PAINTING_H #include #include @@ -7,31 +7,11 @@ #include #include -/* PaintRedrawWindow() control flags */ -#define RDW_EX_USEHRGN 0x0001 -#define RDW_EX_DELETEHRGN 0x0002 -#define RDW_EX_XYWINDOW 0x0004 -#define RDW_EX_TOPFRAME 0x0010 -#define RDW_EX_DELAY_NCPAINT 0x0020 - -/* Update non-client region flags. */ -#define UNC_DELAY_NCPAINT (0x00000001) -#define UNC_IN_BEGINPAINT (0x00000002) -#define UNC_CHECK (0x00000004) -#define UNC_REGION (0x00000008) -#define UNC_ENTIRE (0x00000010) -#define UNC_UPDATE (0x00000020) - -HWND STDCALL -PaintingFindWinToRepaint(HWND hWnd, PW32THREAD Thread); -BOOL STDCALL -PaintRedrawWindow(PWINDOW_OBJECT Wnd, const RECT* UpdateRect, HRGN UpdateRgn, - ULONG Flags, ULONG ExFlags); -BOOL STDCALL -PaintHaveToDelayNCPaint(PWINDOW_OBJECT Window, ULONG Flags); -HRGN STDCALL -PaintUpdateNCRegion(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags); +BOOL FASTCALL +IntRedrawWindow(PWINDOW_OBJECT Wnd, const RECT* UpdateRect, HRGN UpdateRgn, ULONG Flags); +BOOL FASTCALL +IntGetPaintMessage(PWINDOW_OBJECT Window, PW32THREAD Thread, MSG *Message); BOOL STDCALL NtUserValidateRgn(HWND hWnd, HRGN hRgn); -#endif /* __WIN32K_PAINTING_H */ +#endif /* _WIN32K_PAINTING_H */ diff --git a/reactos/subsys/win32k/include/palette.h b/reactos/subsys/win32k/include/palette.h index 84970cf0174..a194c4071d7 100644 --- a/reactos/subsys/win32k/include/palette.h +++ b/reactos/subsys/win32k/include/palette.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_PALETTE_H -#define __WIN32K_PALETTE_H +#ifndef _WIN32K_PALETTE_H +#define _WIN32K_PALETTE_H #define PALETTE_FIXED 0x0001 /* read-only colormap - have to use XAllocColor (if not virtual) */ #define PALETTE_VIRTUAL 0x0002 /* no mapping needed - pixel == pixel color */ @@ -42,4 +42,4 @@ INT FASTCALL PALETTE_ToPhysical (PDC dc, COLORREF color); PPALETTEENTRY FASTCALL ReturnSystemPalette (VOID); -#endif /* __WIN32K_PALETTE_H */ +#endif /* _WIN32K_PALETTE_H */ diff --git a/reactos/subsys/win32k/include/path.h b/reactos/subsys/win32k/include/path.h index f686a4f3539..609b6c41435 100644 --- a/reactos/subsys/win32k/include/path.h +++ b/reactos/subsys/win32k/include/path.h @@ -1,3 +1,6 @@ +#ifndef _WIN32K_PATH_H +#define _WIN32K_PATH_H + BOOL FASTCALL PATH_Arc (PDC dc, INT x1, INT y1, INT x2, INT y2, INT xStart, INT yStart, INT xEnd, INT yEnd); BOOL FASTCALL PATH_AssignGdiPath (GdiPath *pPathDest, const GdiPath *pPathSrc); VOID FASTCALL PATH_DestroyGdiPath (GdiPath *pPath); @@ -27,3 +30,5 @@ BOOL FASTCALL PATH_PathToRegion(const GdiPath *pPath, INT nPolyFillMode, HRGN *p BOOL FASTCALL PATH_ReserveEntries (GdiPath *pPath, INT numEntries); VOID FASTCALL PATH_ScaleNormalizedPoint (FLOAT_POINT corners[], double x, double y, POINT *pPoint); #endif + +#endif /* _WIN32K_PATH_H */ diff --git a/reactos/subsys/win32k/include/prop.h b/reactos/subsys/win32k/include/prop.h index b968ac96326..d206f70b3b1 100644 --- a/reactos/subsys/win32k/include/prop.h +++ b/reactos/subsys/win32k/include/prop.h @@ -3,5 +3,3 @@ #endif /* _WIN32K_PROP_H */ -/* EOF */ - diff --git a/reactos/subsys/win32k/include/rect.h b/reactos/subsys/win32k/include/rect.h index 9a70f7ae6a7..5f1e14b94dc 100644 --- a/reactos/subsys/win32k/include/rect.h +++ b/reactos/subsys/win32k/include/rect.h @@ -1,3 +1,6 @@ +#ifndef _WIN32K_RECT_H +#define _WIN32K_RECT_H + BOOL STDCALL NtGdiUnionRect(PRECT Dest, const RECT* Src1, const RECT* Src2); BOOL STDCALL @@ -10,3 +13,5 @@ BOOL STDCALL NtGdiIntersectRect(PRECT Dest, const RECT* Src1, const RECT* Src2); BOOL STDCALL NtGdiOffsetRect(LPRECT Rect, int x, int y); + +#endif /* _WIN32K_RECT_H */ diff --git a/reactos/subsys/win32k/include/scroll.h b/reactos/subsys/win32k/include/scroll.h index 6ae3c8979d1..6e6d6f84f04 100644 --- a/reactos/subsys/win32k/include/scroll.h +++ b/reactos/subsys/win32k/include/scroll.h @@ -1,2 +1,7 @@ +#ifndef _WIN32K_SCROLL_H +#define _WIN32K_SCROLL_H + DWORD FASTCALL IntCreateScrollBar(PWINDOW_OBJECT Window, LONG idObject); BOOL FASTCALL IntDestroyScrollBar(PWINDOW_OBJECT Window, LONG idObject); + +#endif /* _WIN32K_SCROLL_H */ diff --git a/reactos/subsys/win32k/include/surface.h b/reactos/subsys/win32k/include/surface.h index 1a102834f3d..ce8a6de27c6 100644 --- a/reactos/subsys/win32k/include/surface.h +++ b/reactos/subsys/win32k/include/surface.h @@ -1,7 +1,7 @@ -#ifndef __WIN32K_SURFACE_H -#define __WIN32K_SURFACE_H +#ifndef _WIN32K_SURFACE_H +#define _WIN32K_SURFACE_H INT FASTCALL BitsPerFormat (ULONG Format); ULONG FASTCALL BitmapFormat (WORD Bits, DWORD Compression); -#endif /* __WIN32K_SURFACE_H */ +#endif /* _WIN32K_SURFACE_H */ diff --git a/reactos/subsys/win32k/include/text.h b/reactos/subsys/win32k/include/text.h index 0865c816326..ac35f67dc72 100644 --- a/reactos/subsys/win32k/include/text.h +++ b/reactos/subsys/win32k/include/text.h @@ -1 +1,6 @@ +#ifndef _WIN32K_TEXT_H +#define _WIN32K_TEXT_H + BOOL FASTCALL InitFontSupport(VOID); + +#endif /* _WIN32K_TEXT_H */ diff --git a/reactos/subsys/win32k/include/timer.h b/reactos/subsys/win32k/include/timer.h index ba74439dde6..f2a1d883f67 100644 --- a/reactos/subsys/win32k/include/timer.h +++ b/reactos/subsys/win32k/include/timer.h @@ -1,5 +1,5 @@ -#ifndef _SUBSYS_WIN32K_INCLUDE_TIMER_H -#define _SUBSYS_WIN32K_INCLUDE_TIMER_H +#ifndef _WIN32K_TIMER_H +#define _WIN32K_TIMER_H typedef struct _MSG_TIMER_ENTRY{ LIST_ENTRY ListEntry; @@ -14,4 +14,4 @@ VOID FASTCALL RemoveTimersThread(HANDLE ThreadID); PMSG_TIMER_ENTRY FASTCALL IntRemoveTimer(HWND hWnd, UINT_PTR IDEvent, HANDLE ThreadID, BOOL SysTimer); UINT_PTR FASTCALL IntSetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc, BOOL SystemTimer); -#endif /* ndef _SUBSYS_WIN32K_INCLUDE_TIMER_H */ +#endif /* _WIN32K_TIMER_H */ diff --git a/reactos/subsys/win32k/include/window.h b/reactos/subsys/win32k/include/window.h index 0514943cfc1..ed186099561 100644 --- a/reactos/subsys/win32k/include/window.h +++ b/reactos/subsys/win32k/include/window.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_WINDOW_H -#define __WIN32K_WINDOW_H +#ifndef _WIN32K_WINDOW_H +#define _WIN32K_WINDOW_H struct _PROPERTY; struct _WINDOW_OBJECT; @@ -94,15 +94,20 @@ typedef struct _WINDOW_OBJECT /* Window flags. */ #define WINDOWOBJECT_NEED_SIZE (0x00000001) -/* Not used anymore: define WINDOWOBJECT_NEED_BEGINPAINT (0x00000002) */ -#define WINDOWOBJECT_NEED_ERASEBACKGRD (0x00000004) -#define WINDOWOBJECT_NEED_NCPAINT (0x00000008) -#define WINDOWOBJECT_NEED_INTERNALPAINT (0x00000010) +#define WINDOWOBJECT_NEED_ERASEBKGND (0x00000002) +#define WINDOWOBJECT_NEED_NCPAINT (0x00000004) +#define WINDOWOBJECT_NEED_INTERNALPAINT (0x00000008) #define WINDOWOBJECT_RESTOREMAX (0x00000020) inline BOOL IntIsDesktopWindow(PWINDOW_OBJECT WindowObject); -inline BOOL IntIsBroadcastHwnd( HWND hwnd ); +inline BOOL IntIsBroadcastHwnd(HWND hwnd); + +BOOL FASTCALL +IntIsWindow(HWND hWnd); + +HWND* FASTCALL +IntWinListChildren(PWINDOW_OBJECT Window); BOOLEAN FASTCALL IntWndBelongsToThread(PWINDOW_OBJECT Window, PW32THREAD ThreadData); @@ -160,12 +165,6 @@ IntUnlinkWindow(PWINDOW_OBJECT Wnd); VOID FASTCALL IntLinkWindow(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndParent, PWINDOW_OBJECT WndPrevSibling); -ULONG -UserHasDlgFrameStyle(ULONG Style, ULONG ExStyle); - -ULONG -UserHasThickFrameStyle(ULONG Style, ULONG ExStyle); - PWINDOW_OBJECT FASTCALL IntGetAncestor(PWINDOW_OBJECT Wnd, UINT Type); @@ -194,6 +193,6 @@ DWORD IntRemoveWndProcHandle(WNDPROC Handle); DWORD IntRemoveProcessWndProcHandles(HANDLE ProcessID); DWORD IntAddWndProcHandle(WNDPROC WindowProc, BOOL IsUnicode); -#endif /* __WIN32K_WINDOW_H */ +#endif /* _WIN32K_WINDOW_H */ /* EOF */ diff --git a/reactos/subsys/win32k/include/winpos.h b/reactos/subsys/win32k/include/winpos.h index 4969e74aa29..06fc6436be4 100644 --- a/reactos/subsys/win32k/include/winpos.h +++ b/reactos/subsys/win32k/include/winpos.h @@ -1,3 +1,6 @@ +#ifndef _WIN32K_WINPOS_H +#define _WIN32K_WINPOS_H + /* Undocumented flags. */ #define SWP_NOCLIENTMOVE 0x0800 #define SWP_NOCLIENTSIZE 0x1000 @@ -18,3 +21,5 @@ USHORT STDCALL WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, POINT WinPoint, PWINDOW_OBJECT* Window); VOID FASTCALL WinPosActivateOtherWindow(PWINDOW_OBJECT Window); + +#endif /* _WIN32K_WINPOS_H */ diff --git a/reactos/subsys/win32k/include/winsta.h b/reactos/subsys/win32k/include/winsta.h index 5700ea60916..a2998d4dc33 100644 --- a/reactos/subsys/win32k/include/winsta.h +++ b/reactos/subsys/win32k/include/winsta.h @@ -1,5 +1,5 @@ -#ifndef __WIN32K_WINSTA_H -#define __WIN32K_WINSTA_H +#ifndef _WIN32K_WINSTA_H +#define _WIN32K_WINSTA_H #include #include @@ -61,6 +61,6 @@ IntSetCaptureWindow(struct _WINDOW_OBJECT* Window); BOOL FASTCALL IntGetWindowStationObject(PWINSTATION_OBJECT Object); -#endif /* __WIN32K_WINSTA_H */ +#endif /* _WIN32K_WINSTA_H */ /* EOF */ diff --git a/reactos/subsys/win32k/ntuser/message.c b/reactos/subsys/win32k/ntuser/message.c index 68a55f57fa1..6a7467982a3 100644 --- a/reactos/subsys/win32k/ntuser/message.c +++ b/reactos/subsys/win32k/ntuser/message.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: message.c,v 1.31 2003/11/11 20:28:21 gvg Exp $ +/* $Id: message.c,v 1.32 2003/11/18 20:49:39 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -205,39 +205,10 @@ IntPeekMessage(LPMSG Msg, /* Check for paint messages. */ if (ThreadQueue->PaintPosted) { - PWINDOW_OBJECT WindowObject; - - Msg->hwnd = PaintingFindWinToRepaint(Wnd, PsGetWin32Thread()); - Msg->message = WM_PAINT; - Msg->wParam = Msg->lParam = 0; - - WindowObject = IntGetWindowObject(Msg->hwnd); - if (WindowObject != NULL) - { - if (WindowObject->Style & WS_MINIMIZE && - (HICON)NtUserGetClassLong(Msg->hwnd, GCL_HICON, FALSE) != NULL) - { - Msg->message = WM_PAINTICON; - Msg->wParam = 1; - } - - if (Msg->hwnd == NULL || Msg->hwnd == Wnd || - IntIsChildWindow(Wnd, Msg->hwnd)) - { - if (WindowObject->Flags & WINDOWOBJECT_NEED_INTERNALPAINT && - WindowObject->UpdateRegion == NULL) - { - WindowObject->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT; - if (RemoveMessages) - { - MsqDecPaintCountQueue(WindowObject->MessageQueue); - } - } - } - IntReleaseWindowObject(WindowObject); - } - - return TRUE; + if (IntGetPaintMessage(Wnd, PsGetWin32Thread(), Msg)) + { + return TRUE; + } } return FALSE; diff --git a/reactos/subsys/win32k/ntuser/painting.c b/reactos/subsys/win32k/ntuser/painting.c index 7335d4e76ca..fb11f65a7a2 100644 --- a/reactos/subsys/win32k/ntuser/painting.c +++ b/reactos/subsys/win32k/ntuser/painting.c @@ -15,20 +15,23 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id: painting.c,v 1.33 2003/09/11 22:11:44 gvg Exp $ * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * PURPOSE: Painting - * FILE: subsys/win32k/ntuser/painting.c - * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) - * REVISION HISTORY: - * 06-06-2001 CSH Created + * $Id: painting.c,v 1.34 2003/11/18 20:49:39 navaraf Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Window painting function + * FILE: subsys/win32k/ntuser/painting.c + * PROGRAMER: Filip Navara (xnavara@volny.cz) + * REVISION HISTORY: + * 06/06/2001 Created (?) + * 18/11/2003 Complete rewrite */ + /* INCLUDES ******************************************************************/ #include +#include #include #include #include @@ -47,1005 +50,825 @@ #define NDEBUG #include +/* GLOBALS ********************************************************************/ -/* GLOBALS *******************************************************************/ +/* + * Define this after the desktop will be moved to CSRSS and will + * get proper message queue. + */ +/* #define DESKTOP_IN_CSRSS */ -/* client rect in window coordinates */ -#define GETCLIENTRECTW(wnd, r) (r).left = (wnd)->ClientRect.left - (wnd)->WindowRect.left; \ - (r).top = (wnd)->ClientRect.top - (wnd)->WindowRect.top; \ - (r).right = (wnd)->ClientRect.right - (wnd)->WindowRect.left; \ - (r).bottom = (wnd)->ClientRect.bottom - (wnd)->WindowRect.top +/* PRIVATE FUNCTIONS **********************************************************/ -/* FUNCTIONS *****************************************************************/ +/* + * IntGetNCUpdateRegion + * + * Get nonclient part of window update region. + * + * Return Value + * Handle to region that represents invalid nonclient window area. The + * caller is responsible for deleting it. + * + * Remarks + * This function also marks the nonclient update region of window + * as valid, clears the WINDOWOBJECT_NEED_NCPAINT flag and removes + * the fake paint message from message queue. + */ -HRGN STATIC STDCALL -PaintDoPaint(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, ULONG ExFlags) +HRGN FASTCALL +IntGetNCUpdateRegion(PWINDOW_OBJECT Window) { - HDC hDC; - HWND hWnd = Window->Self; - BOOL bIcon = (0 != (Window->Style & WS_MINIMIZE)) && - (0 != IntGetClassLong(Window, GCL_HICON, FALSE)); + HRGN WindowRgn; + HRGN NonclientRgn; - if (0 != (ExFlags & RDW_EX_DELAY_NCPAINT) || - PaintHaveToDelayNCPaint(Window, 0)) - { - ExFlags |= RDW_EX_DELAY_NCPAINT; - } + Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT; + MsqDecPaintCountQueue(Window->MessageQueue); + WindowRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect); + NtGdiOffsetRgn(WindowRgn, + -Window->WindowRect.left, + -Window->WindowRect.top); + NonclientRgn = NtGdiCreateRectRgn(0, 0, 0, 0); + if (NtGdiCombineRgn(NonclientRgn, Window->UpdateRegion, + WindowRgn, RGN_DIFF) == NULLREGION) + { + NtGdiDeleteObject(NonclientRgn); + NonclientRgn = NULL; + } + if (NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion, + WindowRgn, RGN_AND) == NULLREGION) + { + NtGdiDeleteObject(Window->UpdateRegion); + Window->UpdateRegion = NULL; + } - if (Flags & RDW_UPDATENOW) - { - if (NULL != Window->UpdateRegion) - { - if (IntIsDesktopWindow(Window)) - { - VIS_RepaintDesktop(Window->Self, Window->UpdateRegion); - } - else - { - NtUserSendMessage(hWnd, bIcon ? WM_PAINTICON : WM_PAINT, bIcon, 0); - } - } - } - else if (Flags & RDW_ERASENOW || ExFlags & RDW_EX_TOPFRAME) - { - UINT Dcx = DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN | - DCX_WINDOWPAINT | DCX_CACHE; - HRGN hRgnRet; - - hRgnRet = - PaintUpdateNCRegion(Window, - hRgn, - UNC_REGION | UNC_CHECK | - ((ExFlags & RDW_EX_TOPFRAME) ? UNC_ENTIRE : 0) | - ((ExFlags & RDW_EX_DELAY_NCPAINT) ? - UNC_DELAY_NCPAINT : 0)); - if (NULL != hRgnRet) - { - if ((HRGN) 1 < hRgnRet) - { - hRgn = hRgnRet; - } - else - { - hRgnRet = NULL; - } - if (0 != (Window->Flags & WINDOWOBJECT_NEED_ERASEBACKGRD)) - { - if (bIcon) - { - Dcx |= DCX_WINDOW; - } - if (NULL != hRgnRet) - { - NtGdiOffsetRgn(hRgnRet, - Window->WindowRect.left - - Window->ClientRect.left, - Window->WindowRect.top - - Window->ClientRect.top); - } - else - { - Dcx &= ~DCX_INTERSECTRGN; - } - if (NULL != (hDC = NtUserGetDCEx(hWnd, hRgnRet, Dcx))) - { - if (IntIsDesktopWindow(Window)) - { - VIS_RepaintDesktop(Window->Self, Window->UpdateRegion); - NtGdiDeleteObject(Window->UpdateRegion); - Window->UpdateRegion = 0; - } - else - { - if (0 != NtUserSendMessage(hWnd, bIcon ? WM_ICONERASEBKGND : - WM_ERASEBKGND, (WPARAM)hDC, 0)) - { - Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD; - } - } - NtUserReleaseDC(hWnd, hDC); - } - } - } - } - - /* FIXME: Check that the window is still valid at this point. */ - - ExFlags &= ~RDW_EX_TOPFRAME; - - /* FIXME: Paint child windows. */ - - return(hRgn); + return NonclientRgn; } -VOID STATIC FASTCALL -PaintUpdateInternalPaint(PWINDOW_OBJECT Window, ULONG Flags) +/* + * IntPaintWindows + * + * Internal function used by IntRedrawWindow. + */ + +VOID FASTCALL +IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags) { - if (Flags & RDW_INTERNALPAINT) - { - if (Window->UpdateRegion == NULL && - !(Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)) - { - MsqIncPaintCountQueue(Window->MessageQueue); - } - Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT; - } - else if (Flags & RDW_NOINTERNALPAINT) - { - if (Window->UpdateRegion == NULL && - (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)) - { - MsqDecPaintCountQueue(Window->MessageQueue); - } - Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT; - } + HDC hDC; + HWND hWnd = Window->Self; + + if (!(Window->Style & WS_VISIBLE)) + { + return; + } + + if (Flags & (RDW_ERASENOW | RDW_UPDATENOW)) + { + if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) + { + NtUserSendMessage(hWnd, WM_NCPAINT, (WPARAM)IntGetNCUpdateRegion(Window), 0); + } + + if (Window->Flags & WINDOWOBJECT_NEED_ERASEBKGND) + { + if (Window->UpdateRegion) + { + hDC = NtUserGetDCEx(hWnd, 0, DCX_CACHE | DCX_USESTYLE | + DCX_INTERSECTUPDATE); + if (hDC != NULL) + { +#ifndef DESKTOP_IN_CSRSS + if (IntIsDesktopWindow(Window)) + { + VIS_RepaintDesktop(Window->Self, Window->UpdateRegion); + NtGdiDeleteObject(Window->UpdateRegion); + Window->UpdateRegion = 0; + } + else +#endif + { + if (NtUserSendMessage(hWnd, WM_ERASEBKGND, (WPARAM)hDC, 0)) + Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBKGND; + } + NtUserReleaseDC(hWnd, hDC); + } + } + } + + if (Flags & RDW_UPDATENOW) + { + if (Window->UpdateRegion != NULL || + Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT) + { +#ifndef DESKTOP_IN_CSRSS + if (IntIsDesktopWindow(Window)) + VIS_RepaintDesktop(Window->Self, Window->UpdateRegion); + else +#endif + NtUserSendMessage(hWnd, WM_PAINT, 0, 0); + } + } + } + + /* + * Check that the window is still valid at this point + */ + + if (!IntIsWindow(hWnd)) + return; + + /* + * Paint child windows. + */ + + if (!(Flags & RDW_NOCHILDREN) && !(Window->Style & WS_MINIMIZE) && + ((Flags & RDW_ALLCHILDREN) || !(Window->Style & WS_CLIPCHILDREN))) + { + HWND *List, *phWnd; + + if ((List = IntWinListChildren(Window))) + { + for (phWnd = List; *phWnd; ++phWnd) + { + Window = IntGetWindowObject(*phWnd); + IntPaintWindows(Window, Flags); + IntReleaseWindowObject(Window); + } + ExFreePool(List); + } + } } -VOID STATIC FASTCALL -PaintValidateParent(PWINDOW_OBJECT Child) +/* + * IntInvalidateWindows + * + * Internal function used by IntRedrawWindow. + */ + +VOID FASTCALL +IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags) { - HWND DesktopHandle = IntGetDesktopWindow(); - PWINDOW_OBJECT Parent = Child->Parent; - PWINDOW_OBJECT Desktop = IntGetWindowObject(DesktopHandle); - HRGN hRgn; + INT RgnType; - if ((HRGN) 1 == Child->UpdateRegion) - { - RECT Rect; + if (!(Window->Style & WS_VISIBLE)) + { + return; + } + + /* + * Clip the given region with window rectangle (or region) + */ - Rect.left = Rect.top = 0; - Rect.right = Child->WindowRect.right - Child->WindowRect.left; - Rect.bottom = Child->WindowRect.bottom - Child->WindowRect.top; +#ifdef TODO + if (!Window->WindowRegion) +#endif + { + HRGN hRgnWindow; + hRgnWindow = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect); + NtGdiOffsetRgn(hRgnWindow, + -Window->WindowRect.left, + -Window->WindowRect.top); + RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnWindow, RGN_AND); + } +#ifdef TODO + else + { + RgnType = NtGdiCombineRgn(hRgn, hRgn, Window->WindowRegion, RGN_AND); + } +#endif - hRgn = UnsafeIntCreateRectRgnIndirect(&Rect); - } - else - { - hRgn = Child->UpdateRegion; - } + if (RgnType == NULLREGION) + { + return; + } - while (NULL != Parent && Parent != Desktop) - { - if (0 == (Parent->Style & WS_CLIPCHILDREN)) - { - if (NULL != Parent->UpdateRegion) - { - POINT Offset; + /* + * Remove fake posted paint messages from window message queue + */ - if ((HRGN) 1 == Parent->UpdateRegion) - { - RECT Rect1; +#ifndef DESKTOP_IN_CSRSS + if (!IntIsDesktopWindow(Window)) + { +#endif + if (Window->UpdateRegion != NULL || + Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT) + { + MsqDecPaintCountQueue(Window->MessageQueue); + } - Rect1.left = Rect1.top = 0; - Rect1.right = Parent->WindowRect.right - - Parent->WindowRect.left; - Rect1.bottom = Parent->WindowRect.bottom - - Parent->WindowRect.top; + if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) + { + MsqDecPaintCountQueue(Window->MessageQueue); + } +#ifndef DESKTOP_IN_CSRSS + } +#endif - Parent->UpdateRegion = - UnsafeIntCreateRectRgnIndirect(&Rect1); - } - Offset.x = Child->WindowRect.left - Parent->WindowRect.left; - Offset.y = Child->WindowRect.top - Parent->WindowRect.top; - NtGdiOffsetRgn(hRgn, Offset.x, Offset.y); - NtGdiCombineRgn(Parent->UpdateRegion, Parent->UpdateRegion, hRgn, - RGN_DIFF); - NtGdiOffsetRgn(hRgn, -Offset.x, -Offset.y); - } - } - Parent = Parent->Parent; - } - if (hRgn != Child->UpdateRegion) - { - NtGdiDeleteObject(Child->UpdateRegion); - } - IntReleaseWindowObject(Desktop); -} + /* + * Update the region and flags + */ -VOID STATIC STDCALL -PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, - BOOL First) -{ - /* - * Called only when one of the following is set: - * (RDW_INVALIDATE | RDW_VALIDATE | RDW_INTERNALPAINT | RDW_NOINTERNALPAINT) - */ + if (Flags & RDW_INVALIDATE) + { + if (Window->UpdateRegion == NULL) + { + Window->UpdateRegion = NtGdiCreateRectRgn(0, 0, 0, 0); + } - BOOL HadOne = NULL != Window->UpdateRegion && NULL != hRgn; - BOOL HasChildren = Window->FirstChild && - !(Flags & RDW_NOCHILDREN) && !(Window->Style & WS_MINIMIZE) && - ((Flags & RDW_ALLCHILDREN) || !(Window->Style & WS_CLIPCHILDREN)); - RECT Rect; - - Rect.left = Rect.top = 0; - Rect.right = Window->WindowRect.right - Window->WindowRect.left; - Rect.bottom = Window->WindowRect.bottom - Window->WindowRect.top; - - if (Flags & RDW_INVALIDATE) - { - if ((HRGN) 1 < hRgn) - { - if ((HRGN) 1 != Window->UpdateRegion) - { - if ((HRGN) 1 < Window->UpdateRegion) - { - NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion, - hRgn, RGN_OR); - } - Window->UpdateRegion = - REGION_CropRgn(Window->UpdateRegion, - Window->UpdateRegion ? Window->UpdateRegion : hRgn, - &Rect, NULL); - if (! HadOne) - { - UnsafeIntGetRgnBox(Window->UpdateRegion, &Rect); - if (NtGdiIsEmptyRect(&Rect)) - { - NtGdiDeleteObject(Window->UpdateRegion); - Window->UpdateRegion = NULL; - PaintUpdateInternalPaint(Window, Flags); - return; - } - } - } - } - else if ((HRGN) 1 == hRgn) - { - if ((HRGN) 1 < Window->UpdateRegion) - { - NtGdiDeleteObject(Window->UpdateRegion); - } - Window->UpdateRegion = (HRGN) 1; - } - else - { - hRgn = Window->UpdateRegion; /* this is a trick that depends on code in PaintRedrawWindow() */ - } - - if (! HadOne && 0 == (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT) && - !IntIsDesktopWindow(Window)) - { - MsqIncPaintCountQueue(Window->MessageQueue); - } + if (NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion, + hRgn, RGN_OR) == NULLREGION) + { + NtGdiDeleteObject(Window->UpdateRegion); + Window->UpdateRegion = NULL; + } if (Flags & RDW_FRAME) - { - Window->Flags |= WINDOWOBJECT_NEED_NCPAINT; - } + Window->Flags |= WINDOWOBJECT_NEED_NCPAINT; if (Flags & RDW_ERASE) - { - Window->Flags |= WINDOWOBJECT_NEED_ERASEBACKGRD; - } - Flags |= RDW_FRAME; - } - else if (Flags & RDW_VALIDATE) - { - if (NULL != Window->UpdateRegion) - { - if ((HRGN) 1 < hRgn) - { - if ((HRGN) 1 == Window->UpdateRegion) - { - /* If no NCPAINT needed or if we're going to turn it off - the special value 1 means the whole client rect */ - if (0 == (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) || - 0 != (Flags & RDW_NOFRAME)) - { - Rect.left = Window->ClientRect.left - Window->WindowRect.left; - Rect.top = Window->ClientRect.top - Window->WindowRect.top; - Rect.right = Window->ClientRect.right - Window->WindowRect.left; - Rect.bottom = Window->ClientRect.bottom - Window->WindowRect.top; - } - Window->UpdateRegion = - UnsafeIntCreateRectRgnIndirect(&Rect); - } - if (NtGdiCombineRgn(Window->UpdateRegion, - Window->UpdateRegion, hRgn, - RGN_DIFF) == NULLREGION) - { - NtGdiDeleteObject(Window->UpdateRegion); - Window->UpdateRegion = NULL; - } - } - else /* validate everything */ - { - if ((HRGN) 1 < Window->UpdateRegion) - { - NtGdiDeleteObject(Window->UpdateRegion); - } - Window->UpdateRegion = NULL; - } + Window->Flags |= WINDOWOBJECT_NEED_ERASEBKGND; - if (NULL != Window->UpdateRegion) - { - Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD; - if (0 != (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)) - { - MsqDecPaintCountQueue(Window->MessageQueue); - } - } - } + Flags |= RDW_FRAME; + } + + if (Flags & RDW_VALIDATE) + { + if (Window->UpdateRegion != NULL) + { + if (NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion, + hRgn, RGN_DIFF) == NULLREGION) + { + NtGdiDeleteObject(Window->UpdateRegion); + Window->UpdateRegion = NULL; + } + } if (Flags & RDW_NOFRAME) - { - Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT; - } + Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT; if (Flags & RDW_NOERASE) - { - Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD; - } - } + Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBKGND; + } - if (First && NULL != Window->UpdateRegion && 0 != (Flags & RDW_UPDATENOW)) - { - PaintValidateParent(Window); /* validate parent covered by region */ - } + if (Flags & RDW_INTERNALPAINT) + { + Window->Flags |= WINDOWOBJECT_NEED_INTERNALPAINT; + } - /* in/validate child windows that intersect with the region if it - * is a valid handle. */ + if (Flags & RDW_NOINTERNALPAINT) + { + Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT; + } - if (0 != (Flags & (RDW_INVALIDATE | RDW_VALIDATE))) - { - if ((HRGN) 1 < hRgn && HasChildren) - { - POINT Total = {0, 0}; - POINT PrevOrign = {0, 0}; - PWINDOW_OBJECT Child; + /* + * Fake post paint messages to window message queue + */ - ExAcquireFastMutexUnsafe(&Window->ChildrenListLock); - Child = Window->FirstChild; - while (Child) - { - if (0 != (Child->Style & WS_VISIBLE)) - { - POINT Offset; - - Rect.left = Child->WindowRect.left - Window->WindowRect.left; - Rect.top = Child->WindowRect.top - Window->WindowRect.top; - Rect.right = Child->WindowRect.right - Window->WindowRect.left; - Rect.bottom = Child->WindowRect.bottom - Window->WindowRect.top; - - Offset.x = Rect.left - PrevOrign.x; - Offset.y = Rect.top - PrevOrign.y; - NtGdiOffsetRect(&Rect, -Total.x, -Total.y); - - if (UnsafeIntRectInRegion(hRgn, &Rect)) - { - NtGdiOffsetRgn(hRgn, -Offset.x, -Offset.y); - PaintUpdateRgns(Child, hRgn, Flags, FALSE); - PrevOrign.x = Rect.left + Total.x; - PrevOrign.y = Rect.top + Total.y; - Total.x += Offset.x; - Total.y += Offset.y; - } - } - Child = Child->NextSibling; - } - ExReleaseFastMutexUnsafe(&Window->ChildrenListLock); - - NtGdiOffsetRgn(hRgn, Total.x, Total.y); - HasChildren = FALSE; - } - } - - if (HasChildren) - { - PWINDOW_OBJECT Child; - - ExAcquireFastMutexUnsafe(&Window->ChildrenListLock); - Child = Window->FirstChild; - while (Child) - { - if (Child->Style & WS_VISIBLE) +#ifndef DESKTOP_IN_CSRSS + if (!IntIsDesktopWindow(Window)) + { +#endif + if (Window->UpdateRegion != NULL || + Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT) { - PaintUpdateRgns(Child, hRgn, Flags, FALSE); + MsqIncPaintCountQueue(Window->MessageQueue); } - Child = Child->NextSibling; - } - ExReleaseFastMutexUnsafe(&Window->ChildrenListLock); - } - PaintUpdateInternalPaint(Window, Flags); + if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) + { + MsqIncPaintCountQueue(Window->MessageQueue); + } +#ifndef DESKTOP_IN_CSRSS + } +#endif + + /* + * Process children if needed + */ + + if (!(Flags & RDW_NOCHILDREN) && !(Window->Style & WS_MINIMIZE) && + ((Flags & RDW_ALLCHILDREN) || !(Window->Style & WS_CLIPCHILDREN))) + { + HWND *List, *phWnd; + PWINDOW_OBJECT Child; + + if ((List = IntWinListChildren(Window))) + { + for (phWnd = List; *phWnd; ++phWnd) + { + HRGN hRgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0); + Child = IntGetWindowObject(*phWnd); + NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY); + NtGdiOffsetRgn(hRgnTemp, + Window->WindowRect.left - Child->WindowRect.left, + Window->WindowRect.top - Child->WindowRect.top); + IntInvalidateWindows(Child, hRgnTemp, Flags); + NtGdiDeleteObject(hRgnTemp); + IntReleaseWindowObject(Child); + } + ExFreePool(List); + } + } } -BOOL STDCALL -PaintRedrawWindow( PWINDOW_OBJECT Window, - const RECT* UpdateRect, - HRGN UpdateRgn, - ULONG Flags, - ULONG ExFlags) +VOID FASTCALL +IntValidateParent(PWINDOW_OBJECT Child) { - RECT Rect, Rect2; - POINT Pt; - HRGN hRgn = NULL; + HWND Parent; + PWINDOW_OBJECT ParentWindow; - DPRINT("[win32k.sys:painting] In PaintRedrawWindow()\n"); + Parent = NtUserGetAncestor(Child->Self, GA_PARENT); + while (Parent && Parent != IntGetDesktopWindow()) + { + ParentWindow = IntGetWindowObject(Parent); + if (ParentWindow && !(ParentWindow->Style & WS_CLIPCHILDREN)) + { + if (ParentWindow->UpdateRegion != 0) + { + INT OffsetX, OffsetY; - if ((RDW_INVALIDATE | RDW_FRAME) == (Flags & (RDW_INVALIDATE | RDW_FRAME)) || - (RDW_VALIDATE | RDW_NOFRAME) == (Flags & (RDW_VALIDATE | RDW_NOFRAME))) - { - Rect = Window->WindowRect; - } - else - { - Rect = Window->ClientRect; - } - - if (ExFlags & RDW_EX_XYWINDOW) - { - Pt.x = Pt.y = 0; - NtGdiOffsetRect(&Rect, -Window->WindowRect.left, -Window->WindowRect.top); - } - else - { - Pt.x = Window->ClientRect.left - Window->WindowRect.left; - Pt.y = Window->ClientRect.top - Window->WindowRect.top; - NtGdiOffsetRect(&Rect, -Window->ClientRect.left, -Window->ClientRect.top); - } - - if (0 != (Flags & RDW_INVALIDATE)) /* ------------------------- Invalidate */ - { - if (NULL != UpdateRgn) - { - if (NULL != Window->UpdateRegion) - { - hRgn = REGION_CropRgn(NULL, UpdateRgn, NULL, &Pt); - } - else - { - Window->UpdateRegion = REGION_CropRgn(NULL, UpdateRgn, &Rect, &Pt); - } - } - else if (NULL != UpdateRect) - { - if (! NtGdiIntersectRect(&Rect2, &Rect, UpdateRect)) - { - - if ((HRGN) 1 < hRgn && hRgn != UpdateRgn) - { - NtGdiDeleteObject(hRgn); - } - return TRUE; - } - NtGdiOffsetRect(&Rect2, Pt.x, Pt.y); - if (NULL == Window->UpdateRegion) - { - Window->UpdateRegion = - UnsafeIntCreateRectRgnIndirect(&Rect2); - } - else - { - hRgn = UnsafeIntCreateRectRgnIndirect(&Rect2); - } - } - else /* entire window or client depending on RDW_FRAME */ - { - if (Flags & RDW_FRAME) - { - if (NULL != Window->UpdateRegion) - { - hRgn = (HRGN) 1; - } - else - { - Window->UpdateRegion = (HRGN) 1; - } - } - else - { - GETCLIENTRECTW(Window, Rect2); - if (NULL == Window->UpdateRegion) - { - Window->UpdateRegion = UnsafeIntCreateRectRgnIndirect(&Rect2); - } - else - { - hRgn = UnsafeIntCreateRectRgnIndirect(&Rect2); - } - } - } - } - else if (Flags & RDW_VALIDATE) - { - /* In this we cannot leave with zero hRgn */ - if (NULL != UpdateRgn) - { - hRgn = REGION_CropRgn(hRgn, UpdateRgn, &Rect, &Pt); - UnsafeIntGetRgnBox(hRgn, &Rect2); - if (NtGdiIsEmptyRect(&Rect2)) - { - - if ((HRGN) 1 < hRgn && hRgn != UpdateRgn) - { - NtGdiDeleteObject(hRgn); - } - return TRUE; - } - } - else if (NULL != UpdateRect) - { - if (! NtGdiIntersectRect(&Rect2, &Rect, UpdateRect)) - { - - if ((HRGN) 1 < hRgn && hRgn != UpdateRgn) - { - NtGdiDeleteObject(hRgn); - } - return TRUE; - } - NtGdiOffsetRect(&Rect2, Pt.x, Pt.y); - hRgn = UnsafeIntCreateRectRgnIndirect(&Rect2); - } - else /* entire window or client depending on RDW_NOFRAME */ - { - if (0 != (Flags & RDW_NOFRAME)) - { - hRgn = (HRGN) 1; - } - else - { - GETCLIENTRECTW(Window, Rect2); - hRgn = UnsafeIntCreateRectRgnIndirect(&Rect2); - } - } - } - - /* At this point hRgn is either an update region in window coordinates or 1 or 0 */ - - PaintUpdateRgns(Window, hRgn, Flags, TRUE); - - /* Erase/update windows, from now on hRgn is a scratch region */ - - hRgn = PaintDoPaint(Window, (HRGN) 1 == hRgn ? NULL : hRgn, Flags, ExFlags); - - if ((HRGN) 1 < hRgn && hRgn != UpdateRgn) - { - NtGdiDeleteObject(hRgn); - } - - return TRUE; + /* + * We must offset the child region by the offset of the + * child rect in the parent. + */ + OffsetX = Child->WindowRect.left - ParentWindow->WindowRect.left; + OffsetY = Child->WindowRect.top - ParentWindow->WindowRect.top; + NtGdiOffsetRgn(Child->UpdateRegion, OffsetX, OffsetY ); + NtGdiCombineRgn(ParentWindow->UpdateRegion, ParentWindow->UpdateRegion, + Child->UpdateRegion, RGN_DIFF); + NtGdiOffsetRgn(Child->UpdateRegion, -OffsetX, -OffsetY); + } + } + IntReleaseWindowObject(ParentWindow); + Parent = NtUserGetAncestor(Parent, GA_PARENT); + } } -BOOL STDCALL -PaintHaveToDelayNCPaint(PWINDOW_OBJECT Window, ULONG Flags) +/* + * IntRedrawWindow + * + * Internal version of NtUserRedrawWindow that takes WINDOW_OBJECT as + * first parameter. + */ + +BOOL FASTCALL +IntRedrawWindow(PWINDOW_OBJECT Window, const RECT* UpdateRect, HRGN UpdateRgn, + ULONG Flags) { - if (Flags & UNC_DELAY_NCPAINT) - { - return(TRUE); - } + HRGN hRgn = NULL; - if (Flags & UNC_IN_BEGINPAINT) - { - return(FALSE); - } + /* + * Step 1. + * Validation of passed parameters. + */ - Window = Window->Parent; - while (Window != NULL) - { - if (Window->Style & WS_CLIPCHILDREN && Window->UpdateRegion != NULL) - { - return TRUE; - } - Window = Window->Parent; - } + if ((Flags & (RDW_VALIDATE | RDW_INVALIDATE)) == (RDW_VALIDATE | RDW_INVALIDATE)) + { + return FALSE; + } - return FALSE; + /* + * Step 2. + * Transform the parameters UpdateRgn and UpdateRect into + * a region hRgn specified in window coordinates. + */ + + if (Flags & (RDW_INVALIDATE | RDW_VALIDATE)) + { + if (UpdateRgn != NULL) + { + hRgn = NtGdiCreateRectRgn(0, 0, 0, 0); + NtGdiCombineRgn(hRgn, UpdateRgn, NULL, RGN_COPY); + NtGdiOffsetRgn(hRgn, + Window->ClientRect.left - Window->WindowRect.left, + Window->ClientRect.top - Window->WindowRect.top); + } else + if (UpdateRect != NULL) + { + hRgn = UnsafeIntCreateRectRgnIndirect((RECT *)UpdateRect); + NtGdiOffsetRgn(hRgn, + Window->ClientRect.left - Window->WindowRect.left, + Window->ClientRect.top - Window->WindowRect.top); + } else + if ((Flags & (RDW_INVALIDATE | RDW_FRAME)) == (RDW_INVALIDATE | RDW_FRAME) || + (Flags & (RDW_VALIDATE | RDW_NOFRAME)) == (RDW_VALIDATE | RDW_NOFRAME)) + { + hRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect); + NtGdiOffsetRgn(hRgn, + -Window->WindowRect.left, + -Window->WindowRect.top); + } + else + { + hRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect); + NtGdiOffsetRgn(hRgn, + -Window->WindowRect.left, + -Window->WindowRect.top); + } + } + + /* + * Step 3. + * Adjust the window update region depending on hRgn and flags. + */ + + if (Flags & (RDW_INVALIDATE | RDW_VALIDATE | RDW_INTERNALPAINT | RDW_NOINTERNALPAINT)) + { + IntInvalidateWindows(Window, hRgn, Flags); + } + + /* + * Validate parent covered by region. + */ + + if (Window->UpdateRegion != 0 && Flags & RDW_UPDATENOW) + { + IntValidateParent(Window); + } + + /* + * Step 4. + * Repaint and erase windows if needed. + */ + + if (Flags & (RDW_ERASENOW | RDW_UPDATENOW)) + { + IntPaintWindows(Window, Flags); + } + + /* + * Step 5. + * Cleanup ;-) + */ + + NtGdiDeleteObject(hRgn); + + return TRUE; } HWND STDCALL -PaintingFindWinToRepaint(HWND hWnd, PW32THREAD Thread) +IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread) { - PWINDOW_OBJECT Window; - PWINDOW_OBJECT BaseWindow; - PLIST_ENTRY current_entry; - HWND hFoundWnd = NULL; + PWINDOW_OBJECT Window; + PWINDOW_OBJECT Child; + HWND hFoundWnd = NULL; + + if (hWnd == NULL) + { + PLIST_ENTRY CurrentEntry; - if (hWnd == NULL) - { ExAcquireFastMutex(&Thread->WindowListLock); - current_entry = Thread->WindowListHead.Flink; - while (current_entry != &Thread->WindowListHead) - { - Window = CONTAINING_RECORD(current_entry, WINDOW_OBJECT, - ThreadListEntry); - if (Window->Style & WS_VISIBLE) - { - hFoundWnd = - PaintingFindWinToRepaint(Window->Self, Thread); - if (hFoundWnd != NULL) - { - ExReleaseFastMutex(&Thread->WindowListLock); - return(hFoundWnd); - } - } - current_entry = current_entry->Flink; - } - ExReleaseFastMutex(&Thread->WindowListLock); - return(NULL); - } - BaseWindow = IntGetWindowObject(hWnd); - if (BaseWindow == NULL) - { - return(NULL); - } - if (BaseWindow->UpdateRegion != NULL || - BaseWindow->Flags & WINDOWOBJECT_NEED_INTERNALPAINT) - { - IntReleaseWindowObject(BaseWindow); - return(hWnd); - } - - ExAcquireFastMutex(&BaseWindow->ChildrenListLock); - Window = BaseWindow->FirstChild; - while (Window) - { - if (Window->Style & WS_VISIBLE) - { - hFoundWnd = PaintingFindWinToRepaint(Window->Self, Thread); - if (hFoundWnd != NULL) + for (CurrentEntry = Thread->WindowListHead.Flink; + CurrentEntry != &Thread->WindowListHead; + CurrentEntry = CurrentEntry->Flink) { - break; + Window = CONTAINING_RECORD(CurrentEntry, WINDOW_OBJECT, ThreadListEntry); + if (Window->Style & WS_VISIBLE) + { + hFoundWnd = IntFindWindowToRepaint(Window->Self, Thread); + if (hFoundWnd != NULL) + { + ExReleaseFastMutex(&Thread->WindowListLock); + return hFoundWnd; + } + } } - } - Window = Window->NextSibling; - } - ExReleaseFastMutex(&BaseWindow->ChildrenListLock); - IntReleaseWindowObject(BaseWindow); - return(hFoundWnd); + ExReleaseFastMutex(&Thread->WindowListLock); + return NULL; + } + else + { + Window = IntGetWindowObject(hWnd); + if (Window == NULL) + return NULL; + + if (Window->UpdateRegion != NULL || + Window->Flags & (WINDOWOBJECT_NEED_INTERNALPAINT | WINDOWOBJECT_NEED_NCPAINT)) + { + IntReleaseWindowObject(Window); + return hWnd; + } + + ExAcquireFastMutex(&Window->ChildrenListLock); + for (Child = Window->FirstChild; Child; Child = Child->NextSibling) + { + if (Child->Style & WS_VISIBLE && + (Child->UpdateRegion != NULL || + Child->Flags & WINDOWOBJECT_NEED_INTERNALPAINT || + Child->Flags & WINDOWOBJECT_NEED_NCPAINT)) + { + hFoundWnd = Child->Self; + break; + } + } + + if (hFoundWnd == NULL) + { + for (Child = Window->FirstChild; Child; Child = Child->NextSibling) + { + if (Child->Style & WS_VISIBLE) + { + hFoundWnd = IntFindWindowToRepaint(Child->Self, Thread); + if (hFoundWnd != NULL) + break; + } + } + } + + ExReleaseFastMutex(&Window->ChildrenListLock); + IntReleaseWindowObject(Window); + + return hFoundWnd; + } } -HRGN STDCALL -PaintUpdateNCRegion(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags) +BOOL FASTCALL +IntGetPaintMessage(PWINDOW_OBJECT Wnd, PW32THREAD Thread, MSG *Message) { - HRGN hRgnRet; - RECT ClientRect; - HRGN hClip = NULL; + PWINDOW_OBJECT Window; - /* Desktop has no parent. */ - if (Window->Parent == NULL) - { - Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT; - if ((HRGN) 1 < Window->UpdateRegion) - { - hRgnRet = REGION_CropRgn(hRgn, Window->UpdateRegion, NULL, NULL); - } - else - { - hRgnRet = Window->UpdateRegion; - } - return(hRgnRet); - } + if (Wnd) + Message->hwnd = IntFindWindowToRepaint(Wnd->Self, PsGetWin32Thread()); + else + Message->hwnd = IntFindWindowToRepaint(NULL, PsGetWin32Thread()); -#if 0 /* NtUserGetFOregroundWindow() not implemented yet */ - if ((Window->Self == NtUserGetForegroundWindow()) && - 0 == (Window->Flags & WIN_NCACTIVATED) ) - { - Window->Flags |= WIN_NCACTIVATED; - Flags |= UNC_ENTIRE; - } -#endif + if (Message->hwnd == NULL) + return FALSE; - /* - * If the window's non-client area needs to be painted, - */ - if (0 != (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) && - ! PaintHaveToDelayNCPaint(Window, Flags)) - { - RECT UpdateRegionBox; - RECT Rect; + Window = IntGetWindowObject(Message->hwnd); + if (Window != NULL) + { + if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) + { + Message->message = WM_NCPAINT; + Message->wParam = (WPARAM)IntGetNCUpdateRegion(Window); + Message->lParam = 0; + } else + { + Message->message = WM_PAINT; + Message->wParam = Message->lParam = 0; + if (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT) + { + Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT; + if (Window->UpdateRegion == NULL) + { + MsqDecPaintCountQueue(Window->MessageQueue); + } + } + } - Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT; - GETCLIENTRECTW(Window, ClientRect); + IntReleaseWindowObject(Window); + return TRUE; + } - if ((HRGN) 1 < Window->UpdateRegion) - { - UnsafeIntGetRgnBox(Window->UpdateRegion, &UpdateRegionBox); - NtGdiUnionRect(&Rect, &ClientRect, &UpdateRegionBox); - if (Rect.left != ClientRect.left || Rect.top != ClientRect.top || - Rect.right != ClientRect.right || Rect.bottom != ClientRect.bottom) - { - hClip = Window->UpdateRegion; - Window->UpdateRegion = REGION_CropRgn(hRgn, hClip, - &ClientRect, NULL); - if (Flags & UNC_REGION) - { - hRgnRet = hClip; - } - } - - if (Flags & UNC_CHECK) - { - UnsafeIntGetRgnBox(Window->UpdateRegion, &UpdateRegionBox); - if (NtGdiIsEmptyRect(&UpdateRegionBox)) - { - NtGdiDeleteObject(Window->UpdateRegion); - Window->UpdateRegion = NULL; - if (0 == (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)) - { - MsqDecPaintCountQueue(Window->MessageQueue); - } - Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD; - } - } - - if (0 == hClip && 0 != Window->UpdateRegion) - { - goto copyrgn; - } - } - else if ((HRGN) 1 == Window->UpdateRegion) - { - if (0 != (Flags & UNC_UPDATE)) - { - Window->UpdateRegion = - UnsafeIntCreateRectRgnIndirect(&ClientRect); - } - if (Flags & UNC_REGION) - { - hRgnRet = (HRGN) 1; - } - Flags |= UNC_ENTIRE; - } - } - else /* no WM_NCPAINT unless forced */ - { - if ((HRGN) 1 < Window->UpdateRegion) - { -copyrgn: - if (0 != (Flags & UNC_REGION)) - { - hRgnRet = REGION_CropRgn(hRgn, Window->UpdateRegion, NULL, NULL); - } - } - else if ((HRGN) 1 == Window->UpdateRegion && 0 != (Flags & UNC_UPDATE)) - { - GETCLIENTRECTW(Window, ClientRect); - Window->UpdateRegion = - UnsafeIntCreateRectRgnIndirect(&ClientRect); - if (Flags & UNC_REGION) - { - hRgnRet = (HRGN) 1; - } - } - } - - if (NULL == hClip && 0 != (Flags & UNC_ENTIRE)) - { - if (RtlCompareMemory(&Window->WindowRect, &Window->ClientRect, - sizeof(RECT)) != sizeof(RECT)) - { - hClip = (HRGN) 1; - } - else - { - hClip = NULL; - } - } - - if (NULL != hClip) /* NOTE: WM_NCPAINT allows wParam to be 1 */ - { - if (hClip == hRgnRet && (HRGN) 1 < hRgnRet) - { - hClip = NtGdiCreateRectRgn(0, 0, 0, 0); - NtGdiCombineRgn(hClip, hRgnRet, 0, RGN_COPY); - } - - NtUserSendMessage(Window->Self, WM_NCPAINT, (WPARAM) hClip, 0); - - if ((HRGN) 1 < hClip && hClip != hRgn && hClip != hRgnRet) - { - NtGdiDeleteObject(hClip); - } - - /* FIXME: Need to check the window is still valid. */ - } - return(hRgnRet); + return FALSE; } -BOOL STDCALL -NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT* lPs) -{ - NtUserReleaseDC(hWnd, lPs->hdc); - /* FIXME: Show claret. */ - return(TRUE); -} +/* PUBLIC FUNCTIONS ***********************************************************/ -static -HRGN FASTCALL -GetClientUpdateRegion(PWINDOW_OBJECT Window) -{ - POINT Offset; - RECT Rect; - - if ((DWORD) Window->UpdateRegion <= 1) - { - return Window->UpdateRegion; - } - - Offset.x = Window->WindowRect.left - Window->ClientRect.left; - Offset.y = Window->WindowRect.top - Window->ClientRect.top; - Rect.left = - Offset.x; - Rect.top = - Offset.y; - Rect.right = Rect.left + (Window->ClientRect.right - Window->ClientRect.left); - Rect.bottom = Rect.top + (Window->ClientRect.bottom - Window->ClientRect.top); - - return REGION_CropRgn(NULL, Window->UpdateRegion, &Rect, &Offset); -} +/* + * NtUserBeginPaint + * + * Status + * @implemented + */ HDC STDCALL NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs) { - BOOL IsIcon; - PWINDOW_OBJECT Window; - HRGN UpdateRegion; - RECT ClientRect; - RECT ClipRect; - //NTSTATUS Status; - INT DcxFlags; + PWINDOW_OBJECT Window; + RECT ClientRect; + RECT ClipRect; + INT DcxFlags; - if (!(Window = IntGetWindowObject(hWnd))) - { - SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); - return NULL; - } - - /* Send WM_NCPAINT */ - PaintUpdateNCRegion(Window, 0, UNC_UPDATE | UNC_IN_BEGINPAINT); + if (!(Window = IntGetWindowObject(hWnd))) + { + SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); + return NULL; + } - /* Check ifthe window is still valid. */ - if (!IntGetWindowObject(hWnd)) - { - return 0; - } + NtUserHideCaret(hWnd); - /* retrieve update region */ - UpdateRegion = GetClientUpdateRegion(Window); - if (1 < (DWORD) Window->UpdateRegion) - { - NtGdiDeleteObject(Window->UpdateRegion); - } - Window->UpdateRegion = 0; - if (UpdateRegion != NULL || (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)) - { - MsqDecPaintCountQueue(Window->MessageQueue); - } - Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT; - - /* FIXME: Hide caret. */ - - IsIcon = (Window->Style & WS_MINIMIZE) && IntGetClassLong(Window, GCL_HICON, FALSE); - - DcxFlags = DCX_INTERSECTRGN | DCX_WINDOWPAINT | DCX_USESTYLE; - if (IsIcon) - { - DcxFlags |= DCX_WINDOW; - } - if (IntGetClassLong(Window, GCL_STYLE, FALSE) & CS_PARENTDC) - { + DcxFlags = DCX_INTERSECTUPDATE | DCX_WINDOWPAINT | DCX_USESTYLE; + if (IntGetClassLong(Window, GCL_STYLE, FALSE) & CS_PARENTDC) + { + /* FIXME: Is this correct? */ /* Don't clip the output to the update region for CS_PARENTDC window */ - if ((HRGN) 1 < UpdateRegion) - { - NtGdiDeleteObject(UpdateRegion); - } - UpdateRegion = NULL; - DcxFlags &= ~DCX_INTERSECTRGN; - } - else - { - if (NULL == UpdateRegion) /* empty region, clip everything */ - { - UpdateRegion = NtGdiCreateRectRgn(0, 0, 0, 0); - } - else if ((HRGN) 1 == UpdateRegion) /* whole client area, don't clip */ - { - UpdateRegion = NULL; - DcxFlags &= ~DCX_INTERSECTRGN; - } - } - lPs->hdc = NtUserGetDCEx(hWnd, UpdateRegion, DcxFlags); + DcxFlags &= ~DCX_INTERSECTUPDATE; + } + + lPs->hdc = NtUserGetDCEx(hWnd, 0, DcxFlags); - /* FIXME: Check for DC creation failure. */ + if (!lPs->hdc) + { + return NULL; + } - IntGetClientRect(Window, &ClientRect); - NtGdiGetClipBox(lPs->hdc, &ClipRect); - NtGdiLPtoDP(lPs->hdc, (LPPOINT)&ClipRect, 2); - NtGdiIntersectRect(&lPs->rcPaint, &ClientRect, &ClipRect); - NtGdiDPtoLP(lPs->hdc, (LPPOINT)&lPs->rcPaint, 2); + if (Window->UpdateRegion != NULL) + { + MsqDecPaintCountQueue(Window->MessageQueue); + NtGdiDeleteObject(Window->UpdateRegion); + Window->UpdateRegion = NULL; + } - if (Window->Flags & WINDOWOBJECT_NEED_ERASEBACKGRD) - { - BOOLEAN Result; - Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD; - Result = NtUserSendMessage(hWnd, - IsIcon ? WM_ICONERASEBKGND : WM_ERASEBKGND, - (WPARAM)lPs->hdc, - 0); - lPs->fErase = !Result; - } - else - { + IntGetClientRect(Window, &ClientRect); + NtGdiGetClipBox(lPs->hdc, &ClipRect); + NtGdiLPtoDP(lPs->hdc, (LPPOINT)&ClipRect, 2); + NtGdiIntersectRect(&lPs->rcPaint, &ClientRect, &ClipRect); + NtGdiDPtoLP(lPs->hdc, (LPPOINT)&lPs->rcPaint, 2); + + if (Window->Flags & WINDOWOBJECT_NEED_ERASEBKGND) + { + Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBKGND; + lPs->fErase = !NtUserSendMessage(hWnd, WM_ERASEBKGND, (WPARAM)lPs->hdc, 0); + } + else + { lPs->fErase = FALSE; - } + } - ObmDereferenceObject(Window); - return(lPs->hdc); + IntReleaseWindowObject(Window); + + return lPs->hdc; } -DWORD -STDCALL -NtUserInvalidateRect( - HWND hWnd, - CONST RECT *Rect, - WINBOOL Erase) +/* + * NtUserEndPaint + * + * Status + * @implemented + */ + +BOOL STDCALL +NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT* lPs) { - return NtUserRedrawWindow(hWnd, Rect, 0, RDW_INVALIDATE | (Erase ? RDW_ERASE : 0)); + NtUserReleaseDC(hWnd, lPs->hdc); + NtUserShowCaret(hWnd); + + return TRUE; } -DWORD -STDCALL -NtUserInvalidateRgn( - HWND hWnd, - HRGN Rgn, - WINBOOL Erase) +/* + * NtUserInvalidateRect + * + * Status + * @implemented + */ + +DWORD STDCALL +NtUserInvalidateRect(HWND hWnd, CONST RECT *Rect, BOOL Erase) { - return NtUserRedrawWindow(hWnd, NULL, Rgn, RDW_INVALIDATE | (Erase ? RDW_ERASE : 0)); + return NtUserRedrawWindow(hWnd, Rect, 0, RDW_INVALIDATE | (Erase ? RDW_ERASE : 0)); } -BOOL -STDCALL -NtUserValidateRgn( - HWND hWnd, - HRGN hRgn) +/* + * NtUserInvalidateRgn + * + * Status + * @implemented + */ + +DWORD STDCALL +NtUserInvalidateRgn(HWND hWnd, HRGN Rgn, BOOL Erase) { - return NtUserRedrawWindow(hWnd, NULL, hRgn, RDW_VALIDATE | RDW_NOCHILDREN); + return NtUserRedrawWindow(hWnd, NULL, Rgn, RDW_INVALIDATE | (Erase ? RDW_ERASE : 0)); } -int -STDCALL -NtUserGetUpdateRgn( - HWND hWnd, - HRGN hRgn, - WINBOOL bErase) -{ - PWINDOW_OBJECT Window; - int RegionType; +/* + * NtUserValidateRgn + * + * Status + * @implemented + */ - if (!(Window = IntGetWindowObject(hWnd))) - { - SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); - return ERROR; - } +BOOL STDCALL +NtUserValidateRgn(HWND hWnd, HRGN hRgn) +{ + return NtUserRedrawWindow(hWnd, NULL, hRgn, RDW_VALIDATE | RDW_NOCHILDREN); +} + +/* + * NtUserUpdateWindow + * + * Status + * @implemented + */ + +BOOL STDCALL +NtUserUpdateWindow(HWND hWnd) +{ + return NtUserRedrawWindow(hWnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN); +} + +/* + * NtUserGetUpdateRgn + * + * Status + * @implemented + */ + +INT STDCALL +NtUserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase) +{ + PWINDOW_OBJECT Window; + int RegionType; + + if (!(Window = IntGetWindowObject(hWnd))) + { + SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); + return ERROR; + } - if (NULL == Window->UpdateRegion) - { + if (Window->UpdateRegion == NULL) + { RegionType = (NtGdiSetRectRgn(hRgn, 0, 0, 0, 0) ? NULLREGION : ERROR); - } - else if ((HRGN) 1 == Window->UpdateRegion) - { - RegionType = (NtGdiSetRectRgn(hRgn, - 0, 0, - Window->ClientRect.right - Window->ClientRect.left, - Window->ClientRect.bottom - Window->ClientRect.top) ? - SIMPLEREGION : ERROR); - } - else - { + } + else + { RegionType = NtGdiCombineRgn(hRgn, Window->UpdateRegion, hRgn, RGN_COPY); - NtGdiOffsetRgn(hRgn, Window->WindowRect.left - Window->ClientRect.left, - Window->WindowRect.top - Window->ClientRect.top ); - } + NtGdiOffsetRgn( + hRgn, + Window->WindowRect.left - Window->ClientRect.left, + Window->WindowRect.top - Window->ClientRect.top); + } - if (bErase && - (SIMPLEREGION == RegionType || COMPLEXREGION == RegionType)) - { - PaintRedrawWindow(Window, NULL, NULL, RDW_ERASENOW | RDW_NOCHILDREN, 0); - } + IntReleaseWindowObject(Window); + + if (bErase && RegionType != NULLREGION && RegionType != ERROR) + { + NtUserRedrawWindow(hWnd, NULL, NULL, RDW_ERASENOW | RDW_NOCHILDREN); + } - IntReleaseWindowObject(Window); + return RegionType; +} - return RegionType; +/* + * NtUserGetUpdateRect + * + * Status + * @implemented + */ + +BOOL STDCALL +NtUserGetUpdateRect(HWND hWnd, LPRECT lpRect, BOOL fErase) +{ + HRGN hRgn = NtGdiCreateRectRgn(0, 0, 0, 0); + + if (!lpRect) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + + NtUserGetUpdateRgn(hWnd, hRgn, fErase); + NtGdiGetRgnBox(hRgn, lpRect); + + return lpRect->left < lpRect->right && lpRect->top < lpRect->bottom; +} + +/* + * NtUserRedrawWindow + * + * Status + * @implemented + */ + +BOOL STDCALL +NtUserRedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate, + UINT flags) +{ + RECT SafeUpdateRect; + NTSTATUS Status; + PWINDOW_OBJECT Wnd; + + if (!(Wnd = IntGetWindowObject(hWnd))) + { + SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); + return FALSE; + } + + if (lprcUpdate != NULL) + { + Status = MmCopyFromCaller(&SafeUpdateRect, (PRECT)lprcUpdate, + sizeof(RECT)); + + if (!NT_SUCCESS(Status)) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + } + + Status = IntRedrawWindow(Wnd, NULL == lprcUpdate ? NULL : &SafeUpdateRect, + hrgnUpdate, flags); + + if (!NT_SUCCESS(Status)) + { + /* IntRedrawWindow fails only in case that flags are invalid */ + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + + return TRUE; } /* EOF */ diff --git a/reactos/subsys/win32k/ntuser/stubs.c b/reactos/subsys/win32k/ntuser/stubs.c index ead1b3a8bc9..7287fc66ce0 100644 --- a/reactos/subsys/win32k/ntuser/stubs.c +++ b/reactos/subsys/win32k/ntuser/stubs.c @@ -1,4 +1,4 @@ -/* $Id: stubs.c,v 1.34 2003/11/10 17:44:49 weiden Exp $ +/* $Id: stubs.c,v 1.35 2003/11/18 20:49:39 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -637,18 +637,6 @@ NtUserGetTitleBarInfo( return 0; } -DWORD -STDCALL -NtUserGetUpdateRect( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) -{ - UNIMPLEMENTED - - return 0; -} - DWORD STDCALL NtUserImpersonateDdeClientWindow( diff --git a/reactos/subsys/win32k/ntuser/vis.c b/reactos/subsys/win32k/ntuser/vis.c index 4ed2b13d474..81c1866e10a 100644 --- a/reactos/subsys/win32k/ntuser/vis.c +++ b/reactos/subsys/win32k/ntuser/vis.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: vis.c,v 1.7 2003/09/09 09:39:21 gvg Exp $ + * $Id: vis.c,v 1.8 2003/11/18 20:49:39 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -221,7 +221,6 @@ VIS_RepaintDesktop(HWND Desktop, HRGN RepaintRgn) NtUserReleaseDC(Desktop, dc); } - static VOID FASTCALL GetUncoveredArea(HRGN Uncovered, PWINDOW_OBJECT Parent, PWINDOW_OBJECT TargetChild, BOOL IncludeTarget) @@ -249,7 +248,6 @@ GetUncoveredArea(HRGN Uncovered, PWINDOW_OBJECT Parent, PWINDOW_OBJECT TargetChi } ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock); } - VOID FASTCALL VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window, @@ -303,9 +301,10 @@ VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window, RgnType = NtGdiCombineRgn(DirtyRgn, DirtyRgn, ExposedWindow, RGN_AND); if (NULLREGION != RgnType && ERROR != RgnType) { - PaintRedrawWindow(Sibling, NULL, DirtyRgn, - RDW_INVALIDATE | RDW_FRAME | RDW_ERASE - | RDW_ALLCHILDREN, RDW_EX_XYWINDOW); + NtGdiOffsetRgn(DirtyRgn, -Sibling->ClientRect.left, -Sibling->ClientRect.top); + IntRedrawWindow(Sibling, NULL, DirtyRgn, + RDW_INVALIDATE | RDW_FRAME | RDW_ERASE + | RDW_ALLCHILDREN); } Covered = UnsafeIntCreateRectRgnIndirect(&Sibling->WindowRect); NtGdiCombineRgn(Uncovered, Uncovered, Covered, RGN_DIFF); @@ -329,9 +328,11 @@ VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window, RgnType = NtGdiCombineRgn(DirtyRgn, DirtyRgn, ExposedWindow, RGN_AND); if (NULLREGION != RgnType && ERROR != RgnType) { - PaintRedrawWindow(Parent, NULL, DirtyRgn, - RDW_INVALIDATE | RDW_FRAME | RDW_ERASE - | RDW_NOCHILDREN, RDW_EX_XYWINDOW); + NtGdiOffsetRgn(DirtyRgn, -Parent->ClientRect.left, + -Parent->ClientRect.top); + IntRedrawWindow(Parent, NULL, DirtyRgn, + RDW_INVALIDATE | RDW_FRAME | RDW_ERASE + | RDW_NOCHILDREN); } NtGdiDeleteObject(ExposedWindow); NtGdiDeleteObject(DirtyRgn); diff --git a/reactos/subsys/win32k/ntuser/windc.c b/reactos/subsys/win32k/ntuser/windc.c index 1e8bec92590..f4000d64fc1 100644 --- a/reactos/subsys/win32k/ntuser/windc.c +++ b/reactos/subsys/win32k/ntuser/windc.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: windc.c,v 1.34 2003/10/22 13:34:25 gvg Exp $ +/* $Id: windc.c,v 1.35 2003/11/18 20:49:39 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -433,6 +433,20 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags) Dce->hClipRgn = NULL; } + if (0 != (Flags & DCX_INTERSECTUPDATE) && NULL == ClipRegion) + { + Dce->hClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0); + if (Dce->hClipRgn) + { + if (Window->UpdateRegion) + NtGdiCombineRgn(Dce->hClipRgn, Window->UpdateRegion, NULL, RGN_COPY); + NtGdiOffsetRgn(Dce->hClipRgn, + Window->WindowRect.left - Window->ClientRect.left, + Window->WindowRect.top - Window->ClientRect.top); + } + Flags &= DCX_INTERSECTRGN; + } + if (NULL != ClipRegion) { Dce->hClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0); diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 820b2dd45fd..aeaa6bd20a6 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: window.c,v 1.135 2003/11/12 05:40:59 royce Exp $ +/* $Id: window.c,v 1.136 2003/11/18 20:49:39 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -245,45 +245,37 @@ IntReleaseWindowObject(PWINDOW_OBJECT Window) } /* - * IntBuildChildWindowArray + * IntWinListChildren * * Compile a list of all child window handles from given window. * * Remarks - * This function is similar to Wine WIN_ListChildren, but has different - * syntax. + * This function is similar to Wine WIN_ListChildren. The caller + * must free the returned list with ExFreePool. */ -BOOL FASTCALL -IntBuildChildWindowArray(PWINDOW_OBJECT Window, HWND **Children, unsigned *NumChildren) +HWND* FASTCALL +IntWinListChildren(PWINDOW_OBJECT Window) { PWINDOW_OBJECT Child; - UINT Index; - - *Children = NULL; - *NumChildren = 0; + HWND *List; + UINT Index, NumChildren = 0; ExAcquireFastMutexUnsafe(&Window->ChildrenListLock); - Child = Window->FirstChild; - while (Child) - { - (*NumChildren)++; - Child = Child->NextSibling; - } + for (Child = Window->FirstChild; Child; Child = Child->NextSibling) + ++NumChildren; - if (*NumChildren != 0) + if (NumChildren != 0) { - *Children = ExAllocatePoolWithTag(PagedPool, *NumChildren * sizeof(HWND), TAG_WNAM); - if (*Children != NULL) + List = ExAllocatePool(PagedPool, (NumChildren + 1) * sizeof(HWND)); + if (List != NULL) { for (Child = Window->FirstChild, Index = 0; Child != NULL; Child = Child->NextSibling, ++Index) - { - (*Children)[Index] = Child->Self; - } - ASSERT(Index == *NumChildren); + List[Index] = Child->Self; + List[Index] = NULL; } else { @@ -293,10 +285,9 @@ IntBuildChildWindowArray(PWINDOW_OBJECT Window, HWND **Children, unsigned *NumCh ExReleaseFastMutexUnsafe(&Window->ChildrenListLock); - return ((*NumChildren != 0) && (*Children != NULL)); + return (NumChildren > 0) ? List : NULL; } - /*********************************************************************** * IntDestroyWindow * @@ -308,8 +299,7 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window, BOOLEAN SendMessages) { HWND *Children; - unsigned NumChildren; - unsigned Index; + HWND *ChildHandle; PWINDOW_OBJECT Child; if (! IntWndBelongsToThread(Window, ThreadData)) @@ -319,33 +309,23 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window, } /* free child windows */ - if (IntBuildChildWindowArray(Window, &Children, &NumChildren)) + Children = IntWinListChildren(Window); + if (Children) { - DbgPrint("NumChildren: %d\n", NumChildren); - for (Index = NumChildren; 0 < Index; Index--) + for (ChildHandle = Children; *ChildHandle; ++ChildHandle) { - Child = IntGetProcessWindowObject(ProcessData, Children[Index - 1]); - DbgPrint("Child %d: %x\n", Index - 1, Child); + Child = IntGetProcessWindowObject(ProcessData, *ChildHandle); if (NULL != Child) - { - if (IntWndBelongsToThread(Child, ThreadData)) - { - DbgPrint("Destroying\n"); - IntDestroyWindow(Child, ProcessData, ThreadData, SendMessages); - DbgPrint("End Destroying\n"); - } + { + if (IntWndBelongsToThread(Child, ThreadData)) + IntDestroyWindow(Child, ProcessData, ThreadData, SendMessages); #if 0 /* FIXME */ - else - { - SendMessageW( list[i], WM_WINE_DESTROYWINDOW, 0, 0 ); - } + else + SendMessageW( list[i], WM_WINE_DESTROYWINDOW, 0, 0 ); #endif - } - } - if (0 != NumChildren) - { - ExFreePool(Children); + } } + ExFreePool(Children); } if (SendMessages) @@ -354,9 +334,9 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window, * Clear the update region to make sure no WM_PAINT messages will be * generated for this window while processing the WM_NCDESTROY. */ - PaintRedrawWindow(Window, NULL, 0, - RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_NOCHILDREN, - 0); + IntRedrawWindow(Window, NULL, 0, + RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE | + RDW_NOINTERNALPAINT | RDW_NOCHILDREN); /* * Send the WM_NCDESTROY to the window being destroyed. @@ -486,7 +466,7 @@ IntCreateDesktopWindow(PWINSTATION_OBJECT WindowStation, WindowObject->Class = DesktopClass; WindowObject->ExStyle = 0; WindowObject->Style = WS_VISIBLE; - WindowObject->Flags |= WINDOWOBJECT_NEED_ERASEBACKGRD; + WindowObject->Flags = 0; WindowObject->x = 0; WindowObject->y = 0; WindowObject->Width = Width; @@ -1838,16 +1818,16 @@ NtUserDestroyWindow(HWND Wnd) { int i; BOOL GotOne = FALSE; - HWND *list; - UINT NumChildren; + HWND *Children; + HWND *ChildHandle; PWINDOW_OBJECT Child; - if (IntBuildChildWindowArray(IntGetWindowObject(IntGetDesktopWindow()), - &list, &NumChildren)) + Children = IntWinListChildren(IntGetWindowObject(IntGetDesktopWindow()); + if (Children) { - for (i = 0; i < NumChildren; i++) + for (ChildHandle = Children; *ChildHandle; ++ChildHandle) { - Child = IntGetWindowObject(list[i]); + Child = IntGetWindowObject(*ChildHandle); if (Child->Owner != Window) { continue; @@ -1855,7 +1835,7 @@ NtUserDestroyWindow(HWND Wnd) if (IntWndBelongsToThread(Child, PsGetWin32Thread())) { IntReleaseWindowObject(Child); - NtUserDestroyWindow(list[i]); + NtUserDestroyWindow(*ChildHandle); GotOne = TRUE; continue; } @@ -1866,7 +1846,7 @@ NtUserDestroyWindow(HWND Wnd) } IntReleaseWindowObject(Child); } - ExFreePool(list); + ExFreePool(Children); } if (! GotOne) { @@ -3064,61 +3044,6 @@ NtUserRealChildWindowFromPoint(DWORD Unknown0, } -/* - * @implemented - */ -BOOL -STDCALL -NtUserRedrawWindow -( - HWND hWnd, - CONST RECT *lprcUpdate, - HRGN hrgnUpdate, - UINT flags -) -{ - RECT SafeUpdateRect; - NTSTATUS Status; - PWINDOW_OBJECT Wnd; - - if (!(Wnd = IntGetWindowObject(hWnd))) - { - SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); - return FALSE; - } - - if(NULL != lprcUpdate) - { - Status = MmCopyFromCaller(&SafeUpdateRect, (PRECT)lprcUpdate, sizeof(RECT)); - - if(!NT_SUCCESS(Status)) - { - /* FIXME: set last error */ - return FALSE; - } - } - - - Status = PaintRedrawWindow - ( - Wnd, - NULL == lprcUpdate ? NULL : &SafeUpdateRect, - hrgnUpdate, - flags, - 0 - ); - - - if(!NT_SUCCESS(Status)) - { - /* FIXME: set last error */ - return FALSE; - } - - return TRUE; -} - - /* * @implemented */ @@ -3454,23 +3379,6 @@ NtUserShowWindowAsync(DWORD Unknown0, } -/* - * @implemented - */ -BOOL STDCALL -NtUserUpdateWindow(HWND hWnd) -{ - PWINDOW_OBJECT pWindow = IntGetWindowObject( hWnd); - - if (!pWindow) - return FALSE; - if (pWindow->UpdateRegion) - NtUserSendMessage( hWnd, WM_PAINT,0,0); - IntReleaseWindowObject(pWindow); - return TRUE; -} - - /* * @unimplemented */ diff --git a/reactos/subsys/win32k/ntuser/winpos.c b/reactos/subsys/win32k/ntuser/winpos.c index d2ed2fb7565..8fb5e66cbd9 100644 --- a/reactos/subsys/win32k/ntuser/winpos.c +++ b/reactos/subsys/win32k/ntuser/winpos.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: winpos.c,v 1.40 2003/10/29 16:24:59 navaraf Exp $ +/* $Id: winpos.c,v 1.41 2003/11/18 20:49:39 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -900,7 +900,7 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx, HRGN ClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0); NtGdiCombineRgn(ClipRgn, CopyRgn, NULL, RGN_COPY); Dc = NtUserGetDCEx(Wnd, ClipRgn, DCX_WINDOW | DCX_CACHE | - DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CLIPSIBLINGS ); + DCX_INTERSECTRGN | DCX_CLIPSIBLINGS ); NtGdiBitBlt(Dc, CopyRect.left, CopyRect.top, CopyRect.right - CopyRect.left, CopyRect.bottom - CopyRect.top, Dc, CopyRect.left + (OldWindowRect.left - NewWindowRect.left), @@ -922,19 +922,17 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx, RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, CopyRgn, RGN_DIFF); if (ERROR != RgnType && NULLREGION != RgnType) { - PaintRedrawWindow(Window, NULL, DirtyRgn, - RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | - RDW_ALLCHILDREN | RDW_ERASENOW, - RDW_EX_XYWINDOW | RDW_EX_USEHRGN); + IntRedrawWindow(Window, NULL, DirtyRgn, + RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | + RDW_ALLCHILDREN | RDW_ERASENOW); } NtGdiDeleteObject(DirtyRgn); } else { - PaintRedrawWindow(Window, NULL, NULL, - RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | - RDW_ALLCHILDREN | RDW_ERASENOW, - RDW_EX_XYWINDOW | RDW_EX_USEHRGN); + IntRedrawWindow(Window, NULL, NULL, + RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | + RDW_ALLCHILDREN | RDW_ERASENOW); } } @@ -999,18 +997,13 @@ WinPosShowWindow(HWND Wnd, INT Cmd) { BOOLEAN WasVisible; PWINDOW_OBJECT Window; - NTSTATUS Status; UINT Swp = 0; - RECT NewPos; + RECT NewPos = {0, 0, 0, 0}; BOOLEAN ShowFlag; - HRGN VisibleRgn; +/* HRGN VisibleRgn;*/ - Status = - ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable, - Wnd, - otWindow, - (PVOID*)&Window); - if (!NT_SUCCESS(Status)) + Window = IntGetWindowObject(Wnd); + if (!Window) { return(FALSE); } @@ -1101,60 +1094,50 @@ WinPosShowWindow(HWND Wnd, INT Cmd) */ } - if (Window->Style & WS_CHILD && - !IntIsWindowVisible(Window->Parent->Self) && - (Swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE)) + /* We can't activate a child window */ + if ((Window->Style & WS_CHILD) && + !(Window->ExStyle & WS_EX_MDICHILD)) { - if (Cmd == SW_HIDE) + Swp |= SWP_NOACTIVATE | SWP_NOZORDER; + } + + WinPosSetWindowPos(Wnd, HWND_TOP, NewPos.left, NewPos.top, + NewPos.right, NewPos.bottom, LOWORD(Swp)); + + if (Cmd == SW_HIDE) + { + /* FIXME: This will cause the window to be activated irrespective + * of whether it is owned by the same thread. Has to be done + * asynchronously. + */ + + if (Wnd == IntGetActiveWindow()) + { + WinPosActivateOtherWindow(Window); + } + + /* Revert focus to parent */ + if (Wnd == IntGetFocusWindow() || + IntIsChildWindow(Wnd, IntGetFocusWindow())) { - VisibleRgn = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop, Window, - FALSE, FALSE, FALSE); - Window->Style &= ~WS_VISIBLE; - VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, Window, VisibleRgn); - NtGdiDeleteObject(VisibleRgn); - } - else - { - Window->Style |= WS_VISIBLE; + IntSetFocusWindow(Window->Parent->Self); } } - else + + if (!IntIsWindow(Wnd)) { - if (Window->Style & WS_CHILD && - !(Window->ExStyle & WS_EX_MDICHILD)) - { - Swp |= SWP_NOACTIVATE | SWP_NOZORDER; - } - if (!(Swp & MINMAX_NOSWP)) - { - WinPosSetWindowPos(Wnd, HWND_TOP, NewPos.left, NewPos.top, - NewPos.right, NewPos.bottom, LOWORD(Swp)); - if (Cmd == SW_HIDE) - { - /* Hide the window. */ - if (Wnd == IntGetActiveWindow()) - { - WinPosActivateOtherWindow(Window); - } - /* Revert focus to parent. */ - if (Wnd == IntGetFocusWindow() || - IntIsChildWindow(Wnd, IntGetFocusWindow())) - { - IntSetFocusWindow(Window->Parent->Self); - } - } - } - /* FIXME: Check for window destruction. */ - /* Show title for minimized windows. */ - if (Window->Style & WS_MINIMIZE) - { - WinPosShowIconTitle(Window, TRUE); - } + IntReleaseWindowObject(Window); + return WasVisible; + } + else if (Window->Style & WS_MINIMIZE) + { + WinPosShowIconTitle(Window, TRUE); } if (Window->Flags & WINDOWOBJECT_NEED_SIZE) { - WPARAM wParam = SIZE_RESTORED; + /* should happen only in CreateWindowEx() */ + int wParam = SIZE_RESTORED; Window->Flags &= ~WINDOWOBJECT_NEED_SIZE; if (Window->Style & WS_MAXIMIZE) @@ -1182,8 +1165,8 @@ WinPosShowWindow(HWND Wnd, INT Cmd) WinPosChangeActiveWindow(Wnd, FALSE); } - ObmDereferenceObject(Window); - return(WasVisible); + IntReleaseWindowObject(Window); + return WasVisible; } BOOL STATIC FASTCALL diff --git a/reactos/subsys/win32k/objects/region.c b/reactos/subsys/win32k/objects/region.c index 4ad7b5149a4..f0b499542a1 100644 --- a/reactos/subsys/win32k/objects/region.c +++ b/reactos/subsys/win32k/objects/region.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: region.c,v 1.38 2003/11/08 22:54:26 navaraf Exp $ */ +/* $Id: region.c,v 1.39 2003/11/18 20:49:39 navaraf Exp $ */ #undef WIN32_LEAN_AND_MEAN #include #include @@ -101,6 +101,33 @@ typedef struct _POINTBLOCK { struct _POINTBLOCK *next; } POINTBLOCK; +/* + * This function is left there for debugging purposes. + */ + +VOID FASTCALL +IntDumpRegion(HRGN hRgn) +{ + ROSRGNDATA *Data; + + Data = RGNDATA_LockRgn(hRgn); + if (Data == NULL) + { + DbgPrint("IntDumpRegion called with invalid region!\n"); + return; + } + + DbgPrint("IntDumpRegion(%x): %d,%d-%d,%d %d\n", + hRgn, + Data->rdh.rcBound.left, + Data->rdh.rcBound.top, + Data->rdh.rcBound.right, + Data->rdh.rcBound.bottom, + Data->rdh.iType); + + RGNDATA_UnlockRgn(hRgn); +} + static BOOL FASTCALL REGION_CopyRegion(PROSRGNDATA dst, PROSRGNDATA src) { if(dst != src) // don't want to copy to itself