- Turn off debug print outs.
[reactos.git] / reactos / dll / win32 / gdi32 / misc / misc.c
index ba1ee64..3a3ce0a 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  You should have received a copy of the GNU General Public License along
+ *  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@reactos.com>
  * UPDATE HISTORY:
@@ -28,6 +27,9 @@
 
 #include "precomp.h"
 
+#define NDEBUG
+#include <debug.h>
+
 PGDI_TABLE_ENTRY GdiHandleTable = NULL;
 PGDI_SHARED_HANDLE_TABLE GdiSharedHandleTable = NULL;
 HANDLE CurrentProcessId = NULL;
@@ -35,7 +37,7 @@ DWORD GDI_BatchLimit = 1;
 
 
 BOOL
-STDCALL
+WINAPI
 GdiAlphaBlend(
             HDC hDCDst,
             int DstX,
@@ -73,7 +75,7 @@ GdiAlphaBlend(
  * @implemented
  */
 HGDIOBJ
-STDCALL
+WINAPI
 GdiFixUpHandle(HGDIOBJ hGdiObj)
 {
     PGDI_TABLE_ENTRY Entry;
@@ -95,7 +97,7 @@ GdiFixUpHandle(HGDIOBJ hGdiObj)
  * @implemented
  */
 PVOID
-STDCALL
+WINAPI
 GdiQueryTable(VOID)
 {
   return (PVOID)GdiHandleTable;
@@ -124,7 +126,7 @@ BOOL GdiGetHandleUserData(HGDIOBJ hGdiObj, DWORD ObjectType, PVOID *UserData)
   PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj);
   if((Entry->Type & GDI_ENTRY_BASETYPE_MASK) == ObjectType &&
     ( (Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK ) == 
-                                                                   GDI_HANDLE_GET_TYPE(hGdiObj))
+                                                                GDI_HANDLE_GET_TYPE(hGdiObj))
   {
     HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
     if(pid == NULL || pid == CurrentProcessId)
@@ -136,17 +138,17 @@ BOOL GdiGetHandleUserData(HGDIOBJ hGdiObj, DWORD ObjectType, PVOID *UserData)
       if(Entry->UserData)
       {
          volatile CHAR *Current = (volatile CHAR*)Entry->UserData;
-         _SEH_TRY
+         _SEH2_TRY
          {
            *Current = *Current;
          }
-         _SEH_HANDLE
+         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
          {
            Result = FALSE;
          }
-         _SEH_END
+         _SEH2_END
       }
-       else
+      else
          Result = FALSE; // Can not be zero.
       if (Result) *UserData = Entry->UserData;
       return Result;
@@ -156,19 +158,65 @@ BOOL GdiGetHandleUserData(HGDIOBJ hGdiObj, DWORD ObjectType, PVOID *UserData)
   return FALSE;
 }
 
-PLDC GdiGetLDC(HDC hDC)
+PLDC
+FASTCALL
+GdiGetLDC(HDC hDC)
 {
-    PDC_ATTR Dc_Attr;
-    if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr))
-      return NULL;
-    return Dc_Attr->pvLDC;
+  PDC_ATTR Dc_Attr;
+  PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX((HGDIOBJ) hDC);
+  HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
+  // Don't check the mask, just the object type.
+  if ( Entry->ObjectType == GDIObjType_DC_TYPE &&
+       (pid == NULL || pid == CurrentProcessId) )
+  {
+     BOOL Result = TRUE;
+     if (Entry->UserData)
+     {
+        volatile CHAR *Current = (volatile CHAR*)Entry->UserData;
+        _SEH2_TRY
+        {
+          *Current = *Current;
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+          Result = FALSE;
+        }
+        _SEH2_END
+     }
+     else
+        Result = FALSE;
+
+     if (Result)
+     {
+        Dc_Attr = (PDC_ATTR)Entry->UserData;
+        return Dc_Attr->pvLDC;
+     }
+  }
+  return NULL;
+}
+
+VOID GdiSAPCallback(PLDC pldc)
+{
+    DWORD Time, NewTime = GetTickCount();
+
+    Time = NewTime - pldc->CallBackTick;
+
+    if ( Time < SAPCALLBACKDELAY) return;
+
+    pldc->CallBackTick = NewTime;
+
+    if ( !pldc->pAbortProc(pldc->hDC, 0) )
+    {
+       CancelDC(pldc->hDC);
+       AbortDoc(pldc->hDC);
+    }
 }
 
 /*
  * @implemented
  */
 DWORD
-STDCALL
+WINAPI
 GdiSetBatchLimit(DWORD Limit)
 {
     DWORD OldLimit = GDI_BatchLimit;
@@ -189,7 +237,7 @@ GdiSetBatchLimit(DWORD      Limit)
  * @implemented
  */
 DWORD
-STDCALL
+WINAPI
 GdiGetBatchLimit()
 {
     return GDI_BatchLimit;
@@ -199,14 +247,14 @@ GdiGetBatchLimit()
  * @unimplemented
  */
 BOOL
-STDCALL
+WINAPI
 GdiReleaseDC(HDC hdc)
 {
     return 0;
 }
 
 INT
-STDCALL
+WINAPI
 ExtEscape(HDC hDC,
           int nEscape,
           int cbInput,
@@ -221,17 +269,60 @@ ExtEscape(HDC hDC,
  * @implemented
  */
 VOID
-STDCALL
+WINAPI
 GdiSetLastError(DWORD dwErrCode)
 {
     NtCurrentTeb()->LastErrorValue = (ULONG) dwErrCode;
 }
 
 BOOL
-STDCALL
+WINAPI
 GdiAddGlsBounds(HDC hdc,LPRECT prc)
 {
     //FIXME: Lookup what 0x8000 means
     return NtGdiSetBoundsRect(hdc, prc, 0x8000 |  DCB_ACCUMULATE ) ? TRUE : FALSE;
 }
 
+extern PGDIHANDLECACHE GdiHandleCache;
+
+HGDIOBJ
+FASTCALL
+hGetPEBHandle(HANDLECACHETYPE Type, COLORREF cr)
+{
+   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 PEB 0x%x\n", GdiHandleCache->ulNumHandles[Type], NtCurrentTeb()->ProcessEnvironmentBlock);
+               pRgn_Attr->AttrFlags &= ~ATTR_CACHED;
+               hPtr[Number - 1] = NULL;
+               GdiHandleCache->ulNumHandles[Type]--;
+            }
+         }
+      }
+   }
+   (void)InterlockedExchangePointer((PVOID*)&GdiHandleCache->ulLock, Lock);
+   return Handle;
+}
+