Author: jimtabor
Date: Wed Dec 30 23:56:09 2009
New Revision: 44817
URL:
http://svn.reactos.org/svn/reactos?rev=44817&view=rev
Log:
[Win32k]
- Plugged in region attribute support and added the PEB cache for it as well.
[Gdi32]
- Using CreateRectRgn only with attribute and PEB cache support.
[Testing]
- Wine tests: gdi32; clipping and dc. gdiplus; region. user32; dce. Same results.
- Applications, AbiWord 2.6.8, FF 3.5, miranda 0.7.19 unicode, putty, SeaMonkey 2.0,
WinMerge 2.12.4 and winamp 2.95 rc std. Same results.
Modified:
trunk/reactos/dll/win32/gdi32/misc/misc.c
trunk/reactos/dll/win32/gdi32/objects/region.c
trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c
trunk/reactos/subsystems/win32/win32k/objects/region.c
Modified: trunk/reactos/dll/win32/gdi32/misc/misc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/misc/misc.…
==============================================================================
--- trunk/reactos/dll/win32/gdi32/misc/misc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/misc/misc.c [iso-8859-1] Wed Dec 30 23:56:09 2009
@@ -16,10 +16,9 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* $Id$
- *
+/*
* PROJECT: ReactOS gdi32.dll
- * FILE: lib/gdi32/misc/misc.c
+ * FILE: dll/win32/gdi32/misc/misc.c
* PURPOSE: Miscellaneous functions
* PROGRAMMER: Thomas Weidenmueller <w3seek(a)reactos.com>
* UPDATE HISTORY:
@@ -284,10 +283,46 @@
return NtGdiSetBoundsRect(hdc, prc, 0x8000 | DCB_ACCUMULATE ) ? TRUE : FALSE;
}
+extern PGDIHANDLECACHE GdiHandleCache;
+
HGDIOBJ
FASTCALL
hGetPEBHandle(HANDLECACHETYPE Type, COLORREF cr)
{
- return NULL;
-}
-
+ int Number;
+ HANDLE Lock;
+ HGDIOBJ Handle = NULL;
+
+ Lock = InterlockedCompareExchangePointer( (PVOID*)&GdiHandleCache->ulLock,
+ NtCurrentTeb(),
+ NULL );
+
+ if (Lock) return Handle;
+
+ Number = GdiHandleCache->ulNumHandles[Type];
+
+ if ( Number && Number <= CACHE_REGION_ENTRIES )
+ {
+ if ( Type == hctRegionHandle)
+ {
+ PRGN_ATTR pRgn_Attr;
+ HGDIOBJ *hPtr;
+ hPtr = GdiHandleCache->Handle + CACHE_BRUSH_ENTRIES+CACHE_PEN_ENTRIES;
+ Handle = hPtr[Number - 1];
+
+ if (GdiGetHandleUserData( Handle, GDI_OBJECT_TYPE_REGION, (PVOID)
&pRgn_Attr))
+ {
+ if (pRgn_Attr->AttrFlags & ATTR_CACHED)
+ {
+ DPRINT("Get Handle! Count %d\n",
GdiHandleCache->ulNumHandles[Type]);
+ pRgn_Attr->AttrFlags &= ~ATTR_CACHED;
+ hPtr[Number - 1] = NULL;
+ GdiHandleCache->ulNumHandles[Type]--;
+ }
+ }
+ }
+ }
+ (void)InterlockedExchangePointer((PVOID*)&GdiHandleCache->ulLock, Lock);
+ return Handle;
+}
+
Modified: trunk/reactos/dll/win32/gdi32/objects/region.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/objects/re…
==============================================================================
--- trunk/reactos/dll/win32/gdi32/objects/region.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/objects/region.c [iso-8859-1] Wed Dec 30 23:56:09 2009
@@ -438,39 +438,35 @@
{
PRGN_ATTR pRgn_Attr;
HRGN hrgn;
- int x, y;
-
-//// Remove when Brush/Pen/Rgn Attr is ready!
- return NtGdiCreateRectRgn(x1,y1,x2,y2);
-////
+ int tmp;
/* Normalize points */
- x = x1;
+ tmp = x1;
if ( x1 > x2 )
{
x1 = x2;
- x2 = x;
- }
-
- y = y1;
+ x2 = tmp;
+ }
+
+ tmp = y1;
if ( y1 > y2 )
{
y1 = y2;
- y2 = y;
- }
-
- if ( (UINT)x1 < 0x80000000 ||
- (UINT)y1 < 0x80000000 ||
- (UINT)x2 > 0x7FFFFFFF ||
- (UINT)y2 > 0x7FFFFFFF )
+ y2 = tmp;
+ }
+ /* Check outside 24 bit limit for universal set. Chp 9 Areas, pg 560.*/
+ if ( x1 < -(1<<27) ||
+ y1 < -(1<<27) ||
+ x2 > (1<<27)-1 ||
+ y2 > (1<<27)-1 )
{
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
-// hrgn = hGetPEBHandle(hctRegionHandle, 0);
-
-// if (!hrgn)
+ hrgn = hGetPEBHandle(hctRegionHandle, 0);
+
+ if (!hrgn)
hrgn = NtGdiCreateRectRgn(0, 0, 1, 1);
if (!hrgn)
@@ -478,6 +474,7 @@
if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID)
&pRgn_Attr))
{
+ DPRINT1("No Attr for Region handle!!!\n");
DeleteRegion(hrgn);
return NULL;
}
@@ -778,15 +775,11 @@
nRightRect = nXOffset + nRightRect;
nBottomRect = nYOffset + nBottomRect;
- /* Mask and bit test. */
- if ( ( nLeftRect & 0xF8000000 &&
- (nLeftRect & 0xF8000000) != 0x80000000 ) ||
- ( nTopRect & 0xF8000000 &&
- (nTopRect & 0xF8000000) != 0x80000000 ) ||
- ( nRightRect & 0xF8000000 &&
- (nRightRect & 0xF8000000) != 0x80000000 ) ||
- ( nBottomRect & 0xF8000000 &&
- (nBottomRect & 0xF8000000) != 0x80000000 ) )
+ /* Check 28 bit limit. Chp 9 Areas, pg 560. */
+ if ( nLeftRect < -(1<<27) ||
+ nTopRect < -(1<<27) ||
+ nRightRect > (1<<27)-1 ||
+ nBottomRect > (1<<27)-1 )
{
return ERROR;
}
Modified: trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c [iso-8859-1] Wed Dec 30
23:56:09 2009
@@ -654,6 +654,69 @@
}
+BOOL
+FASTCALL
+bPEBCacheHandle(HGDIOBJ Handle, int oType, PVOID pAttr)
+{
+ PGDIHANDLECACHE GdiHandleCache;
+ HGDIOBJ *hPtr;
+ BOOL Ret = FALSE;
+ int Offset = 0, Number;
+ HANDLE Lock;
+
+ GdiHandleCache =
(PGDIHANDLECACHE)NtCurrentTeb()->ProcessEnvironmentBlock->GdiHandleBuffer;
+
+ switch (oType)
+ {
+ case hctBrushHandle:
+ Offset = 0;
+ break;
+
+ case hctPenHandle:
+ Offset = CACHE_BRUSH_ENTRIES;
+ break;
+
+ case hctRegionHandle:
+ Offset = CACHE_BRUSH_ENTRIES+CACHE_PEN_ENTRIES;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ Lock = InterlockedCompareExchangePointer( (PVOID*)&GdiHandleCache->ulLock,
+ NtCurrentTeb(),
+ NULL );
+ if (Lock) return FALSE;
+
+ _SEH2_TRY
+ {
+ Number = GdiHandleCache->ulNumHandles[oType];
+
+ hPtr = GdiHandleCache->Handle + Offset;
+
+ if ( oType == hctRegionHandle)
+ {
+ if ( Number < CACHE_REGION_ENTRIES )
+ {
+ ((PRGN_ATTR)pAttr)->AttrFlags |= ATTR_CACHED;
+ hPtr[Number] = Handle;
+ GdiHandleCache->ulNumHandles[oType]++;
+ DPRINT("Put Handle Count %d\n",
GdiHandleCache->ulNumHandles[oType]);
+ Ret = TRUE;
+ }
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Ret = FALSE;
+ }
+ _SEH2_END;
+
+ (void)InterlockedExchangePointer((PVOID*)&GdiHandleCache->ulLock, Lock);
+ return Ret;
+}
+
/*!
* Delete GDI object
* \param hObject object handle
@@ -676,11 +739,17 @@
Index = GDI_HANDLE_GET_INDEX(hObject);
Entry = &GdiHandleTable->Entries[Index];
pAttr = Entry->UserData;
-
+
switch (dwObjectType)
{
-// case GDI_OBJECT_TYPE_BRUSH:
+ case GDI_OBJECT_TYPE_BRUSH:
+ break;
+
case GDI_OBJECT_TYPE_REGION:
+ if (bPEBCacheHandle(hObject, hctRegionHandle, pAttr))
+ {
+ return TRUE;
+ }
if (pAttr) FreeObjectAttr(pAttr);
break;
@@ -1485,58 +1554,6 @@
/** PUBLIC FUNCTIONS **********************************************************/
-/*
- Since Brush/Pen and Region objects are sharable,,, we can just use
- UserHeapAlloc to allocate the small attribute objects.
-
- Example Allocating:
-
- // Save Kernel Space Pointer
- (PBRUSH)->pBrushAttr = IntGdiAllocObjAttr(GDIObjType_BRUSH_TYPE);
-
- // Kernel Space to User Space Pointer
- (PGDI_TABLE_ENTRY)->UserData = pBrushAttr;
- // Gdi will adjust for heap delta.
-
- Example Freeing:
-
- (PGDI_TABLE_ENTRY)->UserData = NULL; // Zero the user ptr.
- UserHeapFree((PBRUSH)->pBrushAttr); // Free from kernel ptr.
- (PBRUSH)->pBrushAttr = NULL;
-
- Notes:
- Testing with DC_ATTR works but has drawing difficulties.
- Base on observation, (Over looking the obvious) we need to supply heap delta
- to user space gdi. Now, with testing, looks all normal.
-
- */
-PVOID
-FASTCALL
-IntGdiAllocObjAttr(GDIOBJTYPE Type)
-{
- PVOID pMemAttr = NULL;
-
- switch( Type )
- {
- case GDIObjType_DC_TYPE:
- pMemAttr = UserHeapAlloc(sizeof(DC_ATTR));
- if (pMemAttr) RtlZeroMemory(pMemAttr, sizeof(DC_ATTR));
- break;
- case GDIObjType_RGN_TYPE:
- pMemAttr = UserHeapAlloc(sizeof(RGN_ATTR));
- if (pMemAttr) RtlZeroMemory(pMemAttr, sizeof(RGN_ATTR));
- break;
- case GDIObjType_BRUSH_TYPE:
- pMemAttr = UserHeapAlloc(sizeof(BRUSH_ATTR));
- if (pMemAttr) RtlZeroMemory(pMemAttr, sizeof(BRUSH_ATTR));
- break;
- default:
- break;
- }
- return pMemAttr;
-}
-
-
BOOL
FASTCALL
IntGdiSetBrushOwner(PBRUSH pbr, DWORD OwnerMask)
Modified: trunk/reactos/subsystems/win32/win32k/objects/region.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/region.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/region.c [iso-8859-1] Wed Dec 30
23:56:09 2009
@@ -2034,6 +2034,8 @@
{
HRGN hReg;
PROSRGNDATA pReg;
+ INT Index;
+ PGDI_TABLE_ENTRY Entry;
pReg = (PROSRGNDATA)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_REGION);
if(!pReg)
@@ -2059,6 +2061,10 @@
return NULL;
}
}
+
+ Index = GDI_HANDLE_GET_INDEX(hReg);
+ Entry = &GdiHandleTable->Entries[Index];
+ Entry->UserData = AllocateObjectAttr();
EMPTY_REGION(pReg);
pReg->rdh.dwSize = sizeof(RGNDATAHEADER);
@@ -2085,27 +2091,35 @@
Entry = &GdiHandleTable->Entries[Index];
pRgn_Attr = Entry->UserData;
+
if (pRgn_Attr)
{
- if ( pRgn_Attr->AttrFlags & (ATTR_RGN_VALID|ATTR_RGN_DIRTY) )
- {
- switch (pRgn_Attr->Flags)
+ _SEH2_TRY
+ {
+ if ( pRgn_Attr->AttrFlags & (ATTR_RGN_VALID|ATTR_RGN_DIRTY) )
{
- case NULLREGION:
- EMPTY_REGION( pRgn );
- pRgn_Attr->AttrFlags &= ~ATTR_RGN_DIRTY; // Clear flag in these
cases,
- break;
-
- case SIMPLEREGION:
- REGION_SetRectRgn( pRgn,
- pRgn_Attr->Rect.left,
- pRgn_Attr->Rect.top,
- pRgn_Attr->Rect.right,
- pRgn_Attr->Rect.bottom );
- pRgn_Attr->AttrFlags &= ~ATTR_RGN_DIRTY; // just incase, force a
redraw.
- break;
+ switch (pRgn_Attr->Flags)
+ {
+ case NULLREGION:
+ EMPTY_REGION( pRgn );
+ break;
+
+ case SIMPLEREGION:
+ REGION_SetRectRgn( pRgn,
+ pRgn_Attr->Rect.left,
+ pRgn_Attr->Rect.top,
+ pRgn_Attr->Rect.right,
+ pRgn_Attr->Rect.bottom );
+ break;
+ }
+ pRgn_Attr->AttrFlags &= ~ATTR_RGN_DIRTY;
}
}
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ }
+ _SEH2_END;
+
if (ppRgn_Attr)
*ppRgn_Attr = pRgn_Attr;
}
@@ -2132,17 +2146,25 @@
Entry = &GdiHandleTable->Entries[Index];
pRgn_Attr = Entry->UserData;
- if ( pRgn_Attr )
+
+ _SEH2_TRY
{
- if ( pRgn_Attr->AttrFlags & ATTR_RGN_VALID )
- {
- pRgn_Attr->Flags = REGION_Complexity( pRgn );
- pRgn_Attr->Rect.left = pRgn->rdh.rcBound.left;
- pRgn_Attr->Rect.top = pRgn->rdh.rcBound.top;
- pRgn_Attr->Rect.right = pRgn->rdh.rcBound.right;
- pRgn_Attr->Rect.bottom = pRgn->rdh.rcBound.bottom;
+ if ( pRgn_Attr )
+ {
+ if ( pRgn_Attr->AttrFlags & ATTR_RGN_VALID )
+ {
+ pRgn_Attr->Flags = REGION_Complexity( pRgn );
+ pRgn_Attr->Rect.left = pRgn->rdh.rcBound.left;
+ pRgn_Attr->Rect.top = pRgn->rdh.rcBound.top;
+ pRgn_Attr->Rect.right = pRgn->rdh.rcBound.right;
+ pRgn_Attr->Rect.bottom = pRgn->rdh.rcBound.bottom;
+ }
}
}
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ }
+ _SEH2_END;
}
REGION_UnlockRgn(pRgn);
}