[ros-diffs] [jimtabor] 44817: [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.

jimtabor at svn.reactos.org jimtabor at svn.reactos.org
Wed Dec 30 23:56:09 CET 2009


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.c?rev=44817&r1=44816&r2=44817&view=diff
==============================================================================
--- 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 at 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/region.c?rev=44817&r1=44816&r2=44817&view=diff
==============================================================================
--- 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/objects/gdiobj.c?rev=44817&r1=44816&r2=44817&view=diff
==============================================================================
--- 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/objects/region.c?rev=44817&r1=44816&r2=44817&view=diff
==============================================================================
--- 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);
 }




More information about the Ros-diffs mailing list