diff --git a/reactos/dll/win32/gdi32/objects/dc.c b/reactos/dll/win32/gdi32/objects/dc.c index 04f0d1b6d67..1de4bbbe2e5 100644 --- a/reactos/dll/win32/gdi32/objects/dc.c +++ b/reactos/dll/win32/gdi32/objects/dc.c @@ -1392,7 +1392,7 @@ SelectObject(HDC hDC, return NtGdiSelectBrush(hDC, hGdiObj); case GDI_OBJECT_TYPE_PEN: -// case GDI_OBJECT_TYPE_EXTPEN: + case GDI_OBJECT_TYPE_EXTPEN: #if 0 // enable this when support is ready in win32k hOldObj = pDc_Attr->hpen; pDc_Attr->ulDirty_ |= DC_PEN_DIRTY; diff --git a/reactos/subsystems/win32/win32k/include/brush.h b/reactos/subsystems/win32/win32k/include/brush.h index 5bc33b76dbb..f9f71bdeae8 100644 --- a/reactos/subsystems/win32/win32k/include/brush.h +++ b/reactos/subsystems/win32/win32k/include/brush.h @@ -58,7 +58,7 @@ typedef struct } GDIBRUSHINST, *PGDIBRUSHINST; /* GDI Brush Attributes */ - +#define GDIBRUSH_NEED_FG_CLR 0x0001 #define GDIBRUSH_NEED_BK_CLR 0x0002 /* Background color is needed */ #define GDIBRUSH_DITHER_OK 0x0004 /* Allow color dithering */ #define GDIBRUSH_IS_SOLID 0x0010 /* Solid brush */ @@ -69,7 +69,12 @@ typedef struct #define GDIBRUSH_IS_GLOBAL 0x0200 /* Stock objects */ #define GDIBRUSH_IS_PEN 0x0400 /* Pen */ #define GDIBRUSH_IS_OLDSTYLEPEN 0x0800 /* Geometric pen */ +#define GDIBRUSH_IS_DIBPALCOLORS 0x1000 +#define GDIBRUSH_IS_DIBPALINDICE 0x2000 +#define GDIBRUSH_IS_DEFAULTSTYLE 0x4000 #define GDIBRUSH_IS_MASKING 0x8000 /* Pattern bitmap is used as transparent mask (?) */ +#define GDIBRUSH_IS_INSIDEFRAME 0x00010000 +#define GDIBRUSH_CACHED_ENGINE 0x00040000 #define GDIBRUSH_CACHED_IS_SOLID 0x80000000 #define BRUSHOBJ_AllocBrush() ((PGDIBRUSHOBJ) GDIOBJ_AllocObj(GDIObjType_BRUSH_TYPE)) diff --git a/reactos/subsystems/win32/win32k/include/misc.h b/reactos/subsystems/win32/win32k/include/misc.h index 044a80716b4..39d00cbd069 100644 --- a/reactos/subsystems/win32/win32k/include/misc.h +++ b/reactos/subsystems/win32/win32k/include/misc.h @@ -2,9 +2,34 @@ #define __WIN32K_MISC_H /* W32PROCESS flags */ -#define W32PF_NOWINDOWGHOSTING (0x0001) -#define W32PF_MANUALGUICHECK (0x0002) -#define W32PF_CREATEDWINORDC (0x0004) +#define W32PF_CONSOLEAPPLICATION 0x00000001 +#define W32PF_FORCEOFFFEEDBACK 0x00000002 +#define W32PF_STARTGLASS 0x00000004 +#define W32PF_WOW 0x00000008 +#define W32PF_READSCREENACCESSGRANTED 0x00000010 +#define W32PF_INITIALIZED 0x00000020 +#define W32PF_APPSTARTING 0x00000040 +#define W32PF_WOW64 0x00000080 +#define W32PF_ALLOWFOREGROUNDACTIVATE 0x00000100 +#define W32PF_OWNDCCLEANUP 0x00000200 +#define W32PF_SHOWSTARTGLASSCALLED 0x00000400 +#define W32PF_FORCEBACKGROUNDPRIORITY 0x00000800 +#define W32PF_TERMINATED 0x00001000 +#define W32PF_CLASSESREGISTERED 0x00002000 +#define W32PF_THREADCONNECTED 0x00004000 +#define W32PF_PROCESSCONNECTED 0x00008000 +#define W32PF_WAKEWOWEXEC 0x00010000 +#define W32PF_WAITFORINPUTIDLE 0x00020000 +#define W32PF_IOWINSTA 0x00040000 +#define W32PF_CONSOLEFOREGROUND 0x00080000 +#define W32PF_OLELOADED 0x00100000 +#define W32PF_SCREENSAVER 0x00200000 +#define W32PF_IDLESCREENSAVER 0x00400000 +// ReactOS +#define W32PF_NOWINDOWGHOSTING (0x01000000) +#define W32PF_MANUALGUICHECK (0x02000000) +#define W32PF_CREATEDWINORDC (0x04000000) + ULONG FASTCALL IntSystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni); DWORD STDCALL IntGetQueueStatus(BOOL ClearChanges); diff --git a/reactos/subsystems/win32/win32k/include/pen.h b/reactos/subsystems/win32/win32k/include/pen.h index ac0ee20c6eb..5cda0d3d5e9 100644 --- a/reactos/subsystems/win32/win32k/include/pen.h +++ b/reactos/subsystems/win32/win32k/include/pen.h @@ -8,16 +8,24 @@ #define PENOBJ_AllocPen() ((HPEN)GDIOBJ_AllocObj(GDIObjType_BRUSH_TYPE)) #define PENOBJ_AllocPenWithHandle() ((PGDIBRUSHOBJ)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_PEN)) -#define PENOBJ_FreePen(pBMObj) GDIOBJ_FreeObj((POBJ) pBMObj, GDI_OBJECT_TYPE_PEN) + +#define PENOBJ_FreePen(pBMObj) GDIOBJ_FreeObj((POBJ) pBMObj, GDIObjType_BRUSH_TYPE) #define PENOBJ_FreePenByHandle(hBMObj) GDIOBJ_FreeObjByHandle((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_PEN) -#define PENOBJ_LockPen(hBMObj) ((PGDIBRUSHOBJ)GDIOBJ_LockObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_PEN)) + +//#define PENOBJ_LockPen(hBMObj) ((PGDIBRUSHOBJ)GDIOBJ_LockObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_PEN)) + #define PENOBJ_AllocExtPen() ((PGDIBRUSHOBJ)GDIOBJ_AllocObj(GDIObjType_BRUSH_TYPE)) #define PENOBJ_AllocExtPenWithHandle() ((PGDIBRUSHOBJ)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_EXTPEN)) -#define PENOBJ_FreeExtPen(pBMObj) GDIOBJ_FreeObj((POBJ) pBMObj, GDI_OBJECT_TYPE_EXTPEN) + +#define PENOBJ_FreeExtPen(pBMObj) GDIOBJ_FreeObj((POBJ) pBMObj, GDIObjType_BRUSH_TYPE) #define PENOBJ_FreeExtPenByHandle(hBMObj) GDIOBJ_FreeObjByHandle((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_EXTPEN) -#define PENOBJ_LockExtPen(hBMObj) ((PGDIBRUSHOBJ)GDIOBJ_LockObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_EXTPEN)) + +//#define PENOBJ_LockExtPen(hBMObj) ((PGDIBRUSHOBJ)GDIOBJ_LockObj((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_EXTPEN)) + #define PENOBJ_UnlockPen(pPenObj) GDIOBJ_UnlockObjByPtr((POBJ)pPenObj) + +PGDIBRUSHOBJ FASTCALL PENOBJ_LockPen(HGDIOBJ); INT STDCALL PEN_GetObject(PGDIBRUSHOBJ hPen, INT Count, PLOGPEN Buffer); #endif diff --git a/reactos/subsystems/win32/win32k/objects/pen.c b/reactos/subsystems/win32/win32k/objects/pen.c index 324bcf6874c..018c9d71067 100644 --- a/reactos/subsystems/win32/win32k/objects/pen.c +++ b/reactos/subsystems/win32/win32k/objects/pen.c @@ -27,6 +27,16 @@ /* PRIVATE FUNCTIONS **********************************************************/ +PGDIBRUSHOBJ +FASTCALL +PENOBJ_LockPen(HGDIOBJ hBMObj) +{ + if (GDI_HANDLE_GET_TYPE(hBMObj) == GDI_OBJECT_TYPE_EXTPEN) + return GDIOBJ_LockObj( hBMObj, GDI_OBJECT_TYPE_EXTPEN); + else + return GDIOBJ_LockObj( hBMObj, GDI_OBJECT_TYPE_PEN); +} + HPEN STDCALL IntGdiExtCreatePen( DWORD dwPenStyle, @@ -37,7 +47,7 @@ IntGdiExtCreatePen( IN ULONG_PTR ulHatch, DWORD dwStyleCount, PULONG pStyle, - IN ULONG cjDIB, + IN ULONG cjDIB, // FIXME! We are shipping this too! IN BOOL bOldStylePen, IN OPTIONAL HBRUSH hbrush) { @@ -49,6 +59,8 @@ IntGdiExtCreatePen( static const BYTE PatternDashDot[] = {0xFF, 0x81, 0xC0}; static const BYTE PatternDashDotDot[] = {0xFF, 0x8E, 0x38}; + dwWidth = abs(dwWidth); + if (bOldStylePen) { PenObject = PENOBJ_AllocPenWithHandle(); @@ -66,6 +78,9 @@ IntGdiExtCreatePen( } hPen = PenObject->BaseObject.hHmgr; + // If nWidth is zero, the pen is a single pixel wide, regardless of the current transformation. + if ((bOldStylePen) && (!dwWidth)) dwWidth = 1; + PenObject->ptPenWidth.x = dwWidth; PenObject->ptPenWidth.y = 0; PenObject->ulPenStyle = dwPenStyle; @@ -78,6 +93,10 @@ IntGdiExtCreatePen( PenObject->flAttrs = bOldStylePen? GDIBRUSH_IS_OLDSTYLEPEN : GDIBRUSH_IS_PEN; + // If dwPenStyle is PS_COSMETIC, the width must be set to 1. + if ( !(bOldStylePen) && ((dwPenStyle & PS_TYPE_MASK) == PS_COSMETIC) && ( dwWidth != 1) ) + goto EEXIT; + switch (dwPenStyle & PS_STYLE_MASK) { case PS_NULL: @@ -89,6 +108,8 @@ IntGdiExtCreatePen( break; case PS_ALTERNATE: + /* PS_ALTERNATE is applicable only for cosmetic pens */ + if ((dwPenStyle & PS_TYPE_MASK) == PS_GEOMETRIC) goto EEXIT; PenObject->flAttrs |= GDIBRUSH_IS_BITMAP; PenObject->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternAlternate); break; @@ -115,10 +136,35 @@ IntGdiExtCreatePen( case PS_INSIDEFRAME: /* FIXME: does it need some additional work? */ - PenObject->flAttrs |= GDIBRUSH_IS_SOLID; + /* PS_INSIDEFRAME is applicable only for geometric pens */ + if ((dwPenStyle & PS_TYPE_MASK) == PS_COSMETIC) goto EEXIT; + PenObject->flAttrs |= (GDIBRUSH_IS_SOLID|GDIBRUSH_IS_INSIDEFRAME); break; case PS_USERSTYLE: + if ((dwPenStyle & PS_TYPE_MASK) == PS_COSMETIC) + { + /* FIXME: PS_USERSTYLE workaround */ + DPRINT1("PS_COSMETIC | PS_USERSTYLE not handled\n"); + PenObject->flAttrs |= GDIBRUSH_IS_SOLID; + break; + } + else + { + UINT i; + BOOL has_neg = FALSE, all_zero = TRUE; + + for(i = 0; (i < dwStyleCount) && !has_neg; i++) + { + has_neg = has_neg || (((INT)(pStyle[i])) < 0); + all_zero = all_zero && (pStyle[i] == 0); + } + + if(all_zero || has_neg) + { + goto EEXIT; + } + } /* FIXME: what style here? */ PenObject->flAttrs |= 0; break; @@ -127,8 +173,16 @@ IntGdiExtCreatePen( DPRINT1("IntGdiExtCreatePen unknown penstyle %x\n", dwPenStyle); } PENOBJ_UnlockPen(PenObject); - return hPen; + +EEXIT: + SetLastWin32Error(ERROR_INVALID_PARAMETER); + PENOBJ_UnlockPen(PenObject); + if (bOldStylePen) + PENOBJ_FreePenByHandle(hPen); + else + PENOBJ_FreeExtPenByHandle(hPen); + return NULL; } VOID FASTCALL @@ -201,9 +255,10 @@ NtGdiCreatePen( COLORREF Color, IN HBRUSH hbr) { - if (PenStyle > PS_INSIDEFRAME) + if ( PenStyle < PS_SOLID || PenStyle > PS_INSIDEFRAME ) { - PenStyle = PS_SOLID; + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return NULL; } return IntGdiExtCreatePen(PenStyle, @@ -237,8 +292,10 @@ NtGdiExtCreatePen( DWORD* pSafeStyle = NULL; HPEN hPen; + if (dwStyleCount < 0) return 0; if (dwStyleCount > 16) { + SetLastWin32Error(ERROR_INVALID_PARAMETER); return 0; } @@ -281,12 +338,7 @@ NtGdiExtCreatePen( cjDIB, bOldStylePen, hBrush); - - if ((!hPen) && (pSafeStyle)) - { - ExFreePool(pSafeStyle); - } - +// BRUSH_Cleanup takes care of pSafeStyle return hPen; }