From e80e96bff47888a8dc5c7b29885e83936dee9066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Fri, 26 Sep 2003 20:58:06 +0000 Subject: [PATCH] - Incomplete implementation of ReleaseDC() - Fix pen color bug if pen was selected into a DC more than once - Cache GetSysColorBrush() and GetSysColorPen() svn path=/trunk/; revision=6151 --- reactos/include/win32k/dc.h | 3 + reactos/include/win32k/pen.h | 3 +- reactos/lib/user32/windows/dc.c | 7 +-- reactos/lib/user32/windows/defwnd.c | 38 ++++++++++-- reactos/subsys/win32k/ntuser/windc.c | 80 ++++++++++++++++++++++--- reactos/subsys/win32k/objects/dc.c | 45 ++++++++++++-- reactos/subsys/win32k/objects/objconv.c | 4 +- 7 files changed, 156 insertions(+), 24 deletions(-) diff --git a/reactos/include/win32k/dc.h b/reactos/include/win32k/dc.h index 1a8c8b0fd25..5b1ac5c4ef5 100644 --- a/reactos/include/win32k/dc.h +++ b/reactos/include/win32k/dc.h @@ -171,6 +171,7 @@ HGDIOBJ STDCALL NtGdiGetCurrentObject(HDC hDC, UINT ObjectType); VOID FASTCALL IntGetCurrentPositionEx (PDC dc, LPPOINT currentPosition); BOOL STDCALL NtGdiGetCurrentPositionEx(HDC hDC, LPPOINT currentPosition); BOOL STDCALL NtGdiGetDCOrgEx(HDC hDC, LPPOINT Point); +HDC STDCALL NtGdiGetDCState(HDC hDC); INT STDCALL NtGdiGetDeviceCaps(HDC hDC, INT Index); INT STDCALL NtGdiGetMapMode(HDC hDC); INT STDCALL NtGdiGetObject(HGDIOBJ hGDIObj, @@ -193,6 +194,8 @@ BOOL STDCALL NtGdiRestoreDC(HDC hDC, INT SavedDC); INT STDCALL NtGdiSaveDC(HDC hDC); HGDIOBJ STDCALL NtGdiSelectObject(HDC hDC, HGDIOBJ hGDIObj); INT STDCALL NtGdiSetBkMode(HDC hDC, INT backgroundMode); +VOID STDCALL NtGdiSetDCState ( HDC hDC, HDC hDCSave ); +WORD STDCALL NtGdiSetHookFlags(HDC hDC, WORD Flags); INT STDCALL NtGdiSetPolyFillMode(HDC hDC, INT polyFillMode); INT STDCALL NtGdiSetRelAbs(HDC hDC, INT relAbsMode); INT STDCALL NtGdiSetROP2(HDC hDC, INT ROPmode); diff --git a/reactos/include/win32k/pen.h b/reactos/include/win32k/pen.h index 0d9a8143550..f7842eca2e2 100644 --- a/reactos/include/win32k/pen.h +++ b/reactos/include/win32k/pen.h @@ -7,7 +7,8 @@ /* GDI logical pen object */ typedef struct { - LOGPEN logpen; + LOGPEN logpen; + ULONG iSolidColor; } PENOBJ, *PPENOBJ; /* Internal interface */ diff --git a/reactos/lib/user32/windows/dc.c b/reactos/lib/user32/windows/dc.c index 72c333617e6..e8030e037f1 100644 --- a/reactos/lib/user32/windows/dc.c +++ b/reactos/lib/user32/windows/dc.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: dc.c,v 1.13 2003/08/17 09:17:04 weiden Exp $ +/* $Id: dc.c,v 1.14 2003/09/26 20:58:06 gvg Exp $ * * PROJECT: ReactOS user32.dll * FILE: lib/user32/windows/input.c @@ -73,7 +73,7 @@ GetWindowDC( /* - * @unimplemented + * @implemented */ int STDCALL @@ -81,8 +81,7 @@ ReleaseDC( HWND hWnd, HDC hDC) { - UNIMPLEMENTED; - return 0; + return NtUserReleaseDC(hWnd, hDC); } diff --git a/reactos/lib/user32/windows/defwnd.c b/reactos/lib/user32/windows/defwnd.c index c91cfa7c4df..6614243468d 100644 --- a/reactos/lib/user32/windows/defwnd.c +++ b/reactos/lib/user32/windows/defwnd.c @@ -1,4 +1,4 @@ -/* $Id: defwnd.c,v 1.88 2003/09/21 06:44:51 gvg Exp $ +/* $Id: defwnd.c,v 1.89 2003/09/26 20:58:06 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -41,7 +41,7 @@ static HBITMAP hbScrRight; */ -static COLORREF SysColours[29] = +static COLORREF SysColours[] = { RGB(224, 224, 224) /* COLOR_SCROLLBAR */, RGB(58, 110, 165) /* COLOR_BACKGROUND */, @@ -146,7 +146,22 @@ GetSysColor(int nIndex) HPEN STDCALL GetSysColorPen(int nIndex) { - return CreatePen(PS_SOLID, 1, SysColours[nIndex]); + static HPEN SysPens[sizeof(SysColours) / sizeof(SysColours[0])]; + + if (nIndex < 0 || sizeof(SysColours) / sizeof(SysColours[0]) < nIndex) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + /* FIXME should register this object with DeleteObject() so it + can't be deleted */ + if (NULL == SysPens[nIndex]) + { + SysPens[nIndex] = CreatePen(PS_SOLID, 1, SysColours[nIndex]); + } + + return SysPens[nIndex]; } /* @@ -155,7 +170,22 @@ GetSysColorPen(int nIndex) HBRUSH STDCALL GetSysColorBrush(int nIndex) { - return CreateSolidBrush(SysColours[nIndex]); + static HBRUSH SysBrushes[sizeof(SysColours) / sizeof(SysColours[0])]; + + if (nIndex < 0 || sizeof(SysColours) / sizeof(SysColours[0]) < nIndex) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + /* FIXME should register this object with DeleteObject() so it + can't be deleted */ + if (NULL == SysBrushes[nIndex]) + { + SysBrushes[nIndex] = (HBRUSH) ((DWORD) CreateSolidBrush(SysColours[nIndex]) | 0x00800000); + } + + return SysBrushes[nIndex]; } /* diff --git a/reactos/subsys/win32k/ntuser/windc.c b/reactos/subsys/win32k/ntuser/windc.c index df7f15e0e31..e1d6c748213 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.24 2003/09/24 16:01:32 weiden Exp $ +/* $Id: windc.c,v 1.25 2003/09/26 20:58:05 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -48,6 +48,7 @@ /* GLOBALS *******************************************************************/ static PDCE FirstDce = NULL; +static HDC defaultDCstate; #define DCX_CACHECOMPAREMASK (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | \ DCX_CACHE | DCX_WINDOW | DCX_PARENTCLIP) @@ -114,19 +115,14 @@ DceGetVisRgn(HWND hWnd, ULONG Flags, HWND hWndChild, ULONG CFlags) return VisRgn; } -INT STDCALL -NtUserReleaseDC(HWND hWnd, HDC hDc) -{ - return 1; -} - HDC STDCALL NtUserGetDC(HWND hWnd) { return NtUserGetDCEx(hWnd, NULL, NULL == hWnd ? DCX_CACHE | DCX_WINDOW : DCX_USESTYLE); } -PDCE FASTCALL DceAllocDCE(HWND hWnd, DCE_TYPE Type) +PDCE FASTCALL +DceAllocDCE(HWND hWnd, DCE_TYPE Type) { HDCE DceHandle; DCE* Dce; @@ -137,6 +133,10 @@ PDCE FASTCALL DceAllocDCE(HWND hWnd, DCE_TYPE Type) Dce = DCEOBJ_LockDCE(DceHandle); Dce->hDC = NtGdiCreateDC(L"DISPLAY", NULL, NULL, NULL); + if (NULL == defaultDCstate) + { + defaultDCstate = NtGdiGetDCState(Dce->hDC); + } Dce->hwndCurrent = hWnd; Dce->hClipRgn = NULL; Dce->next = FirstDce; @@ -219,6 +219,44 @@ DceDeleteClipRgn(DCE* Dce) Dce->DCXFlags |= DCX_DCEDIRTY; } +STATIC INT FASTCALL +DceReleaseDC(DCE* dce) +{ + if (DCX_DCEBUSY != (dce->DCXFlags & (DCX_DCEEMPTY | DCX_DCEBUSY))) + { + return 0; + } + +#if 0 + /* restore previous visible region */ + + if ((dce->DCXFlags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) && + (dce->DCXFlags & (DCX_CACHE | DCX_WINDOWPAINT)) ) + { + DceDeleteClipRgn( dce ); + } + + if (dce->DCXFlags & DCX_CACHE) + { + /* make the DC clean so that SetDCState doesn't try to update the vis rgn */ + NtGdiSetHookFlags(dce->hDC, DCHF_VALIDATEVISRGN); + NtGdiSetDCState(dce->hDC, defaultDCstate); + dce->DCXFlags &= ~DCX_DCEBUSY; + if (dce->DCXFlags & DCX_DCEDIRTY) + { + /* don't keep around invalidated entries + * because SetDCState() disables hVisRgn updates + * by removing dirty bit. */ + dce->hwndCurrent = 0; + dce->DCXFlags &= DCX_CACHE; + dce->DCXFlags |= DCX_DCEEMPTY; + } + } +#endif + + return 1; +} + HDC STDCALL NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags) { @@ -489,6 +527,32 @@ IntWindowFromDC(HDC hDc) } return 0; } + +INT STDCALL +NtUserReleaseDC(HWND hWnd, HDC hDc) +{ + DCE *dce; + INT nRet = 0; + + /* FIXME USER_Lock(); */ + dce = FirstDce; + + DPRINT("%p %p\n", hWnd, hDc); + + while (dce && (dce->hDC != hDc)) + { + dce = dce->next; + } + + if (dce && (dce->DCXFlags & DCX_DCEBUSY)) + { + nRet = DceReleaseDC(dce); + } + + /* FIXME USER_Unlock(); */ + + return nRet; +} /* EOF */ diff --git a/reactos/subsys/win32k/objects/dc.c b/reactos/subsys/win32k/objects/dc.c index 68919ea4256..cfe65ab2129 100644 --- a/reactos/subsys/win32k/objects/dc.c +++ b/reactos/subsys/win32k/objects/dc.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: dc.c,v 1.82 2003/09/26 10:45:45 gvg Exp $ +/* $Id: dc.c,v 1.83 2003/09/26 20:58:06 gvg Exp $ * * DC.C - Device context functions * @@ -42,6 +42,7 @@ #include #include "../eng/clip.h" #include "../eng/handle.h" +#include #include #include #include @@ -694,7 +695,7 @@ NtGdiSetBkColor(HDC hDC, COLORREF color) return oldColor; } -static HDC STDCALL +HDC STDCALL NtGdiGetDCState(HDC hDC) { PDC newdc, dc; @@ -793,9 +794,9 @@ NtGdiGetDCState(HDC hDC) return hnewdc; } -STATIC + VOID -FASTCALL +STDCALL NtGdiSetDCState ( HDC hDC, HDC hDCSave ) { PDC dc, dcs; @@ -883,6 +884,8 @@ NtGdiSetDCState ( HDC hDC, HDC hDCSave ) dc->w.hClipRgn = 0; } CLIPPING_UpdateGCRegion( dc ); +#else + NtGdiSelectClipRgn(hDC, dcs->w.hClipRgn); #endif NtGdiSelectObject( hDC, dcs->w.hBitmap ); @@ -1449,7 +1452,7 @@ NtGdiSelectObject(HDC hDC, HGDIOBJ hGDIObj) pen = PENOBJ_LockPen(dc->w.hPen); if( pen ) { - pen->logpen.lopnColor = XLATEOBJ_iXlate(XlateObj, pen->logpen.lopnColor); + pen->iSolidColor = XLATEOBJ_iXlate(XlateObj, pen->logpen.lopnColor); PENOBJ_UnlockPen(dc->w.hPen); } EngDeleteXlate(XlateObj); @@ -1557,6 +1560,38 @@ NtGdiSelectObject(HDC hDC, HGDIOBJ hGDIObj) return objOrg; } +WORD STDCALL +NtGdiSetHookFlags(HDC hDC, WORD Flags) +{ + WORD wRet; + DC *dc = DC_LockDc(hDC); + + if (NULL == dc) + { + return 0; + } + + wRet = dc->w.flags & DC_DIRTY; + + /* "Undocumented Windows" info is slightly confusing. + */ + + DPRINT("DC %p, Flags %04x\n", hDC, Flags); + + if (Flags & DCHF_INVALIDATEVISRGN) + { + dc->w.flags |= DC_DIRTY; + } + else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags) + { + dc->w.flags &= ~DC_DIRTY; + } + + DC_UnlockDc(hDC); + + return wRet; +} + DC_SET_MODE( NtGdiSetBkMode, w.backgroundMode, TRANSPARENT, OPAQUE ) DC_SET_MODE( NtGdiSetPolyFillMode, w.polyFillMode, ALTERNATE, WINDING ) // DC_SET_MODE( NtGdiSetRelAbs, w.relAbsMode, ABSOLUTE, RELATIVE ) diff --git a/reactos/subsys/win32k/objects/objconv.c b/reactos/subsys/win32k/objects/objconv.c index 1f66557c0fd..ecefd3dc816 100644 --- a/reactos/subsys/win32k/objects/objconv.c +++ b/reactos/subsys/win32k/objects/objconv.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: objconv.c,v 1.12 2003/08/20 07:45:02 gvg Exp $ */ +/* $Id: objconv.c,v 1.13 2003/09/26 20:58:06 gvg Exp $ */ #undef WIN32_LEAN_AND_MEAN #include @@ -49,7 +49,7 @@ PenToBrushObj ( BRUSHOBJ *brush, PENOBJ *pen ) if ( pen->logpen.lopnStyle == PS_NULL ) brush->logbrush.lbStyle = BS_NULL; else - brush->iSolidColor = pen->logpen.lopnColor; + brush->iSolidColor = pen->iSolidColor; return brush; }