From 85be5ff46cac6ef418590487bb863273edd58d88 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Tue, 1 May 2007 22:04:47 +0000 Subject: [PATCH] Extpen implementation: - give GDI_OBJECT_TYPE_EXTPEN a sizeof(GDIBRUSHOBJ) and EXTPEN_Cleanup function in GDI_OBJ_INFO table - define PENOBJ_AllocExtPen, PENOBJ_FreeExtPen, PENOBJ_LockExtPen needed by IntGdiExtCreatePen - create A Tag for extpen for tagged pool that holds style dwords - implement IntGdiExtCreatePen - implement EXTPEN_Cleanup, freeing the stylebuffer - implement NtGdiExtCreatePen - make CreateStockObjects, NtGdiCreatePen(Indirect) call IntGdiExtCreatePen - remove IntGdiCreatePenIndirect svn path=/trunk/; revision=26619 --- .../subsystems/win32/win32k/include/intgdi.h | 4 +- reactos/subsystems/win32/win32k/include/pen.h | 4 + .../subsystems/win32/win32k/include/tags.h | 1 + .../subsystems/win32/win32k/objects/gdiobj.c | 2 +- reactos/subsystems/win32/win32k/objects/pen.c | 290 +++++++++++++----- .../win32/win32k/objects/stockobj.c | 8 +- reactos/subsystems/win32/win32k/stubs/stubs.c | 2 + reactos/subsystems/win32/win32k/win32k.rbuild | 1 + 8 files changed, 236 insertions(+), 76 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/intgdi.h b/reactos/subsystems/win32/win32k/include/intgdi.h index 473e83dffc4..fc6c2dc9594 100644 --- a/reactos/subsystems/win32/win32k/include/intgdi.h +++ b/reactos/subsystems/win32/win32k/include/intgdi.h @@ -49,8 +49,8 @@ IntGdiSetSolidBrushColor(HBRUSH hBrush, COLORREF Color); /* Pen functions */ -HPEN FASTCALL -IntGdiCreatePenIndirect(PLOGPEN lgpn); +HPEN STDCALL +IntGdiExtCreatePen(DWORD, DWORD, IN ULONG, IN ULONG, IN ULONG_PTR, IN ULONG_PTR, DWORD, PULONG, IN ULONG, IN BOOL, IN OPTIONAL HBRUSH); VOID FASTCALL IntGdiSetSolidPenColor(HPEN hPen, COLORREF Color); diff --git a/reactos/subsystems/win32/win32k/include/pen.h b/reactos/subsystems/win32/win32k/include/pen.h index c5deeb9a1cb..558ddfa5994 100644 --- a/reactos/subsystems/win32/win32k/include/pen.h +++ b/reactos/subsystems/win32/win32k/include/pen.h @@ -9,8 +9,12 @@ #define PENOBJ_AllocPen() ((HPEN)GDIOBJ_AllocObj(GdiHandleTable, GDI_OBJECT_TYPE_PEN)) #define PENOBJ_FreePen(hBMObj) GDIOBJ_FreeObj(GdiHandleTable, (HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_PEN) #define PENOBJ_LockPen(hBMObj) ((PGDIBRUSHOBJ)GDIOBJ_LockObj(GdiHandleTable, (HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_PEN)) +#define PENOBJ_AllocExtPen() ((HPEN)GDIOBJ_AllocObj(GdiHandleTable, GDI_OBJECT_TYPE_EXTPEN)) +#define PENOBJ_FreeExtPen(hBMObj) GDIOBJ_FreeObj(GdiHandleTable, (HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_EXTPEN) +#define PENOBJ_LockExtPen(hBMObj) ((PGDIBRUSHOBJ)GDIOBJ_LockObj(GdiHandleTable, (HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_EXTPEN)) #define PENOBJ_UnlockPen(pPenObj) GDIOBJ_UnlockObjByPtr(GdiHandleTable, pPenObj) INT STDCALL PEN_GetObject(PGDIBRUSHOBJ hPen, INT Count, PLOGPEN Buffer); +BOOL INTERNAL_CALL EXTPEN_Cleanup(PVOID ObjectBody); #endif diff --git a/reactos/subsystems/win32/win32k/include/tags.h b/reactos/subsystems/win32/win32k/include/tags.h index e5a97b29911..559c6cfe933 100644 --- a/reactos/subsystems/win32/win32k/include/tags.h +++ b/reactos/subsystems/win32/win32k/include/tags.h @@ -43,6 +43,7 @@ #define TAG_PRINT TAG('P', 'R', 'N', 'T') /* print */ #define TAG_REGION TAG('R', 'G', 'N', 'O') /* region */ #define TAG_GDITEXT TAG('T', 'X', 'T', 'O') /* text */ +#define TAG_EXTPEN TAG('X', 'P', 'E', 'N') /* extpen */ /* Eng objects */ #define TAG_CLIPOBJ TAG('C', 'L', 'P', 'O') /* clip object */ diff --git a/reactos/subsystems/win32/win32k/objects/gdiobj.c b/reactos/subsystems/win32/win32k/objects/gdiobj.c index b45bfe8c87a..4200ad42f85 100644 --- a/reactos/subsystems/win32/win32k/objects/gdiobj.c +++ b/reactos/subsystems/win32/win32k/objects/gdiobj.c @@ -80,7 +80,7 @@ GDI_OBJ_INFO ObjInfo[] = {GDI_OBJECT_TYPE_DCE, sizeof(DCE), DCE_Cleanup}, {GDI_OBJECT_TYPE_DIRECTDRAW, sizeof(DD_DIRECTDRAW), DD_Cleanup}, {GDI_OBJECT_TYPE_DD_SURFACE, sizeof(DD_SURFACE), DDSURF_Cleanup}, - {GDI_OBJECT_TYPE_EXTPEN, 0, GDI_CleanupDummy}, + {GDI_OBJECT_TYPE_EXTPEN, sizeof(GDIBRUSHOBJ), EXTPEN_Cleanup}, {GDI_OBJECT_TYPE_METADC, 0, GDI_CleanupDummy}, {GDI_OBJECT_TYPE_METAFILE, 0, GDI_CleanupDummy}, {GDI_OBJECT_TYPE_ENHMETAFILE, 0, GDI_CleanupDummy}, diff --git a/reactos/subsystems/win32/win32k/objects/pen.c b/reactos/subsystems/win32/win32k/objects/pen.c index 98bf3071d31..5359a3991ba 100644 --- a/reactos/subsystems/win32/win32k/objects/pen.c +++ b/reactos/subsystems/win32/win32k/objects/pen.c @@ -27,19 +27,37 @@ /* PRIVATE FUNCTIONS **********************************************************/ -HPEN FASTCALL -IntGdiCreatePenIndirect(PLOGPEN LogPen) +HPEN STDCALL +IntGdiExtCreatePen( + DWORD dwPenStyle, + DWORD dwWidth, + IN ULONG ulBrushStyle, + IN ULONG ulColor, + IN ULONG_PTR ulClientHatch, + IN ULONG_PTR ulHatch, + DWORD dwStyleCount, + PULONG pStyle, + IN ULONG cjDIB, + IN BOOL bOldStylePen, + IN OPTIONAL HBRUSH hbrush) { HPEN hPen; PGDIBRUSHOBJ PenObject; - static const WORD wPatternAlternate[] = {0x5555}; - static const WORD wPatternDash[] = {0x0F0F}; - static const WORD wPatternDot[] = {0x3333}; + static const BYTE PatternAlternate[] = {0x55, 0x55, 0x55}; + static const BYTE PatternDash[] = {0xFF, 0xFF, 0xC0}; + static const BYTE PatternDot[] = {0xE3, 0x8E, 0x38}; + static const BYTE PatternDashDot[] = {0xFF, 0x81, 0xC0}; + static const BYTE PatternDashDotDot[] = {0xFF, 0x8E, 0x38}; - if (LogPen->lopnStyle > PS_INSIDEFRAME) - return 0; + if (bOldStylePen) + { + hPen = PENOBJ_AllocPen(); + } + else + { + hPen = PENOBJ_AllocExtPen(); + } - hPen = PENOBJ_AllocPen(); if (!hPen) { SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); @@ -47,13 +65,29 @@ IntGdiCreatePenIndirect(PLOGPEN LogPen) return 0; } - PenObject = PENOBJ_LockPen(hPen); + if (bOldStylePen) + { + PenObject = PENOBJ_LockPen(hPen); + } + else + { + PenObject = PENOBJ_LockExtPen(hPen); + } /* FIXME - Handle PenObject == NULL!!! */ - PenObject->ptPenWidth = LogPen->lopnWidth; - PenObject->ulPenStyle = LogPen->lopnStyle; - PenObject->BrushAttr.lbColor = LogPen->lopnColor; - PenObject->flAttrs = GDIBRUSH_IS_OLDSTYLEPEN; - switch (LogPen->lopnStyle) + + PenObject->ptPenWidth.x = dwWidth; + PenObject->ptPenWidth.y = 0; + PenObject->ulPenStyle = dwPenStyle; + PenObject->BrushAttr.lbColor = ulColor; + PenObject->ulStyle = ulBrushStyle; + // FIXME: copy the bitmap first ? + PenObject->hbmClient = (HANDLE)ulClientHatch; + PenObject->dwStyleCount = dwStyleCount; + PenObject->pStyle = pStyle; + + PenObject->flAttrs = bOldStylePen? GDIBRUSH_IS_OLDSTYLEPEN : GDIBRUSH_IS_PEN; + + switch (dwPenStyle & PS_STYLE_MASK) { case PS_NULL: PenObject->flAttrs |= GDIBRUSH_IS_NULL; @@ -65,17 +99,27 @@ IntGdiCreatePenIndirect(PLOGPEN LogPen) case PS_ALTERNATE: PenObject->flAttrs |= GDIBRUSH_IS_BITMAP; - PenObject->hbmPattern = NtGdiCreateBitmap(8, 1, 1, 1, (LPBYTE)wPatternAlternate); + PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternAlternate); break; case PS_DOT: PenObject->flAttrs |= GDIBRUSH_IS_BITMAP; - PenObject->hbmPattern = NtGdiCreateBitmap(8, 1, 1, 1, (LPBYTE)wPatternDot); + PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDot); break; case PS_DASH: PenObject->flAttrs |= GDIBRUSH_IS_BITMAP; - PenObject->hbmPattern = NtGdiCreateBitmap(8, 1, 1, 1, (LPBYTE)wPatternDash); + PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDash); + break; + + case PS_DASHDOT: + PenObject->flAttrs |= GDIBRUSH_IS_BITMAP; + PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDot); + break; + + case PS_DASHDOTDOT: + PenObject->flAttrs |= GDIBRUSH_IS_BITMAP; + PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDotDot); break; case PS_INSIDEFRAME: @@ -83,34 +127,91 @@ IntGdiCreatePenIndirect(PLOGPEN LogPen) PenObject->flAttrs |= GDIBRUSH_IS_SOLID; break; - default: - DPRINT1("FIXME: IntGdiCreatePenIndirect is UNIMPLEMENTED pen %x\n",LogPen->lopnStyle); - } + case PS_USERSTYLE: + /* FIXME: what style here? */ + PenObject->flAttrs |= 0; + break; + default: + DPRINT1("IntGdiExtCreatePen unknown penstyle %x\n", dwPenStyle); + } PENOBJ_UnlockPen(PenObject); return hPen; } -INT STDCALL -PEN_GetObject(PGDIBRUSHOBJ PenObject, INT Count, PLOGPEN Buffer) +VOID FASTCALL +IntGdiSetSolidPenColor(HPEN hPen, COLORREF Color) { - - LOGPEN LogPen; + PGDIBRUSHOBJ PenObject; - if( Buffer == NULL ) return sizeof(LOGPEN); - if (Count < sizeof(LOGPEN)) return 0; - if (Count > sizeof(LOGPEN)) Count = sizeof(LOGPEN); + PenObject = PENOBJ_LockPen(hPen); + if (PenObject) + { + if (PenObject->flAttrs & GDIBRUSH_IS_SOLID) + { + PenObject->BrushAttr.lbColor = Color & 0xFFFFFF; + } + PENOBJ_UnlockPen(PenObject); + } +} - if( Buffer == NULL ) return sizeof(LOGPEN); +INT STDCALL +PEN_GetObject(PGDIBRUSHOBJ pPenObject, INT cbCount, PLOGPEN pBuffer) +{ + PLOGPEN pLogPen; + PEXTLOGPEN pExtLogPen; + INT cbRetCount; - LogPen.lopnWidth = PenObject->ptPenWidth; - LogPen.lopnStyle = PenObject->ulPenStyle; - LogPen.lopnColor = PenObject->BrushAttr.lbColor; - memcpy(Buffer, &LogPen, Count); + if (pPenObject->flAttrs & GDIBRUSH_IS_OLDSTYLEPEN) + { + cbRetCount = sizeof(LOGPEN); + if (pBuffer) + { + if (cbCount < cbRetCount) return 0; + pLogPen = (PLOGPEN)pBuffer; + pLogPen->lopnWidth = pPenObject->ptPenWidth; + pLogPen->lopnStyle = pPenObject->ulPenStyle; + pLogPen->lopnColor = pPenObject->BrushAttr.lbColor; + } + } + else + { + // FIXME: Can we trust in dwStyleCount being <= 16? + cbRetCount = sizeof(EXTLOGPEN) - sizeof(DWORD) + pPenObject->dwStyleCount * sizeof(DWORD); + if (pBuffer) + { + INT i; - return Count; + if (cbCount < cbRetCount) return 0; + pExtLogPen = (PEXTLOGPEN)pBuffer; + pExtLogPen->elpPenStyle = pPenObject->ulPenStyle; + pExtLogPen->elpWidth = pPenObject->ptPenWidth.x; + pExtLogPen->elpBrushStyle = pPenObject->ulStyle; + pExtLogPen->elpColor = pPenObject->BrushAttr.lbColor; + pExtLogPen->elpHatch = (ULONG_PTR)pPenObject->hbmClient; + pExtLogPen->elpNumEntries = pPenObject->dwStyleCount; + for (i = 0; i < pExtLogPen->elpNumEntries; i++) + { + pExtLogPen->elpStyleEntry[i] = pPenObject->pStyle[i]; + } + } + } + return cbRetCount; +} + +BOOL INTERNAL_CALL +EXTPEN_Cleanup(PVOID ObjectBody) +{ + PGDIBRUSHOBJ pPenObject = (PGDIBRUSHOBJ)ObjectBody; + + /* Free the kmode Styles array */ + if (pPenObject->pStyle) + { + ExFreePool(pPenObject->pStyle); + } + return TRUE; } /* PUBLIC FUNCTIONS ***********************************************************/ @@ -122,20 +223,28 @@ NtGdiCreatePen( COLORREF Color, IN HBRUSH hbr) { - LOGPEN LogPen; + if (PenStyle > PS_INSIDEFRAME) + { + PenStyle = PS_SOLID; + } - LogPen.lopnStyle = PenStyle; - LogPen.lopnWidth.x = Width; - LogPen.lopnWidth.y = 0; - LogPen.lopnColor = Color; - - return IntGdiCreatePenIndirect(&LogPen); + return IntGdiExtCreatePen(PenStyle, + Width, + BS_SOLID, + Color, + 0, + 0, + 0, + NULL, + 0, + TRUE, + 0); } HPEN STDCALL NtGdiCreatePenIndirect(CONST PLOGPEN LogPen) { - LOGPEN SafeLogPen; + LOGPEN SafeLogPen = {0}; NTSTATUS Status = STATUS_SUCCESS; _SEH_TRY @@ -157,46 +266,89 @@ NtGdiCreatePenIndirect(CONST PLOGPEN LogPen) return 0; } - return IntGdiCreatePenIndirect(&SafeLogPen); + return IntGdiExtCreatePen(SafeLogPen.lopnStyle, + SafeLogPen.lopnWidth.x, + BS_SOLID, + SafeLogPen.lopnColor, + 0, + 0, + 0, + NULL, + 0, + TRUE, + 0); } HPEN STDCALL NtGdiExtCreatePen( - DWORD PenStyle, - DWORD Width, - IN ULONG iBrushStyle, + DWORD dwPenStyle, + DWORD ulWidth, + IN ULONG ulBrushStyle, IN ULONG ulColor, - IN ULONG_PTR lClientHatch, - IN ULONG_PTR lHatch, - DWORD StyleCount, - PULONG Style, + IN ULONG_PTR ulClientHatch, + IN ULONG_PTR ulHatch, + DWORD dwStyleCount, + PULONG pUnsafeStyle, IN ULONG cjDIB, IN BOOL bOldStylePen, - IN OPTIONAL HBRUSH hbrush) + IN OPTIONAL HBRUSH hBrush) { - LOGPEN LogPen; + NTSTATUS Status = STATUS_SUCCESS; + DWORD* pSafeStyle = NULL; + HPEN hPen; - if (PenStyle & PS_USERSTYLE) - PenStyle = (PenStyle & ~PS_STYLE_MASK) | PS_SOLID; + if (dwStyleCount > 16) + { + return 0; + } - LogPen.lopnStyle = PenStyle & PS_STYLE_MASK; - LogPen.lopnWidth.x = Width; - LogPen.lopnColor = ulColor; + if (dwStyleCount > 0) + { + pSafeStyle = ExAllocatePoolWithTag(NonPagedPool, dwStyleCount * sizeof(DWORD), TAG_EXTPEN); + if (!pSafeStyle) + { + SetLastNtError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + _SEH_TRY + { + ProbeForRead(pUnsafeStyle, dwStyleCount * sizeof(DWORD), 1); + RtlCopyMemory(pSafeStyle, + pUnsafeStyle, + dwStyleCount * sizeof(DWORD)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + ExFreePool(pSafeStyle); + return 0; + } + } - return IntGdiCreatePenIndirect(&LogPen); + hPen = IntGdiExtCreatePen(dwPenStyle, + ulWidth, + ulBrushStyle, + ulColor, + ulClientHatch, + ulHatch, + dwStyleCount, + pSafeStyle, + cjDIB, + bOldStylePen, + hBrush); + + if ((!hPen) && (pSafeStyle)) + { + ExFreePool(pSafeStyle); + } + + return hPen; } -VOID FASTCALL -IntGdiSetSolidPenColor(HPEN hPen, COLORREF Color) -{ - PGDIBRUSHOBJ PenObject; - - PenObject = PENOBJ_LockPen(hPen); - if (PenObject->flAttrs & GDIBRUSH_IS_SOLID) - { - PenObject->BrushAttr.lbColor = Color & 0xFFFFFF; - } - PENOBJ_UnlockPen(PenObject); -} /* EOF */ diff --git a/reactos/subsystems/win32/win32k/objects/stockobj.c b/reactos/subsystems/win32/win32k/objects/stockobj.c index 991079055c3..a9125bbbc7e 100644 --- a/reactos/subsystems/win32/win32k/objects/stockobj.c +++ b/reactos/subsystems/win32/win32k/objects/stockobj.c @@ -130,9 +130,9 @@ CreateStockObjects(void) StockObjects[BLACK_BRUSH] = IntGdiCreateSolidBrush(RGB(0,0,0)); StockObjects[NULL_BRUSH] = IntGdiCreateNullBrush(); - StockObjects[WHITE_PEN] = IntGdiCreatePenIndirect(&WhitePen); - StockObjects[BLACK_PEN] = IntGdiCreatePenIndirect(&BlackPen); - StockObjects[NULL_PEN] = IntGdiCreatePenIndirect(&NullPen); + StockObjects[WHITE_PEN] = IntGdiExtCreatePen(WhitePen.lopnStyle, WhitePen.lopnWidth.x, BS_SOLID, WhitePen.lopnColor, 0, 0, 0, NULL, 0, TRUE, NULL); + StockObjects[BLACK_PEN] = IntGdiExtCreatePen(BlackPen.lopnStyle, BlackPen.lopnWidth.x, BS_SOLID, BlackPen.lopnColor, 0, 0, 0, NULL, 0, TRUE, NULL); + StockObjects[NULL_PEN] = IntGdiExtCreatePen(NullPen.lopnStyle, NullPen.lopnWidth.x, BS_SOLID, NullPen.lopnColor, 0, 0, 0, NULL, 0, TRUE, NULL); (void) TextIntCreateFontIndirect(&OEMFixedFont, (HFONT*)&StockObjects[OEM_FIXED_FONT]); (void) TextIntCreateFontIndirect(&AnsiFixedFont, (HFONT*)&StockObjects[ANSI_FIXED_FONT]); @@ -296,7 +296,7 @@ CreateSysColorObjects(VOID) if(SysColorPens[i] == NULL) { Pen.lopnColor = SysColors[i]; - SysColorPens[i] = IntGdiCreatePenIndirect(&Pen); + SysColorPens[i] = IntGdiExtCreatePen(Pen.lopnStyle, Pen.lopnWidth.x, BS_SOLID, Pen.lopnColor, 0, 0, 0, NULL, 0, TRUE, NULL); if(SysColorPens[i] != NULL) { GDIOBJ_ConvertToStockObj(GdiHandleTable, (HGDIOBJ*)&SysColorPens[i]); diff --git a/reactos/subsystems/win32/win32k/stubs/stubs.c b/reactos/subsystems/win32/win32k/stubs/stubs.c index c7705651f2a..bc3a28f7a8c 100644 --- a/reactos/subsystems/win32/win32k/stubs/stubs.c +++ b/reactos/subsystems/win32/win32k/stubs/stubs.c @@ -60,6 +60,7 @@ EngUnmapFontFile ( ULONG_PTR iFile ) return EngUnmapFontFileFD ( iFile ); } +#if 0 /* * @unimplemented */ @@ -82,6 +83,7 @@ EngTextOut ( UNIMPLEMENTED; return FALSE; } +#endif /* * @unimplemented diff --git a/reactos/subsystems/win32/win32k/win32k.rbuild b/reactos/subsystems/win32/win32k/win32k.rbuild index 59f5f1a9b8c..6effabf47ab 100644 --- a/reactos/subsystems/win32/win32k/win32k.rbuild +++ b/reactos/subsystems/win32/win32k/win32k.rbuild @@ -65,6 +65,7 @@ semaphor.c sort.c surface.c + engtext.c transblt.c engwindow.c xlate.c