Author: tkreuzer
Date: Sat May 1 15:02:46 2010
New Revision: 47074
URL:
http://svn.reactos.org/svn/reactos?rev=47074&view=rev
Log:
[GDI32]
- Fix pointer arithmetics in the gdi batch code (&pTeb->GdiTebBatch.Buffer[0] is a
PULONG, but pTeb->GdiTebBatch.Offset is a byte offset)
- To prevent this from happening again, refactor the code to use one common routine
GdiAllocBatchCommand to do most of the stuff.
- Reenable gdi batch for SelectObject
- Fixes gdi handle leak, causes some drawing problems in Acrobat reader, but those are
less critical and I'll investigate those.
Modified:
trunk/reactos/dll/win32/gdi32/include/gdi32p.h
trunk/reactos/dll/win32/gdi32/objects/dc.c
trunk/reactos/dll/win32/gdi32/objects/region.c
Modified: trunk/reactos/dll/win32/gdi32/include/gdi32p.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/include/gd…
==============================================================================
--- trunk/reactos/dll/win32/gdi32/include/gdi32p.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/include/gdi32p.h [iso-8859-1] Sat May 1 15:02:46 2010
@@ -292,4 +292,91 @@
BOOL FASTCALL EndPagePrinterEx(PVOID,HANDLE);
BOOL FASTCALL LoadTheSpoolerDrv(VOID);
+
+FORCEINLINE
+PVOID
+GdiAllocBatchCommand(
+ HDC hdc,
+ USHORT Cmd)
+{
+ PTEB pTeb;
+ ULONG ulSize;
+ PGDIBATCHHDR pHdr;
+
+ /* Get a pointer to the TEB */
+ pTeb = NtCurrentTeb();
+
+ /* Check if we have a valid environment */
+ if (!pTeb || !pTeb->Win32ThreadInfo) return NULL;
+
+ /* Do we use a DC? */
+ if (hdc)
+ {
+ /* If the batch DC is NULL, we set this one as the new one */
+ if (!pTeb->GdiTebBatch.HDC) pTeb->GdiTebBatch.HDC = hdc;
+
+ /* If not, check if the batch DC equal to our DC */
+ else if (pTeb->GdiTebBatch.HDC != hdc) return NULL;
+ }
+
+ /* Get the size of the entry */
+ switch(Cmd)
+ {
+ case GdiBCPatBlt:
+ ulSize = 0;
+ break;
+ case GdiBCPolyPatBlt:
+ ulSize = 0;
+ break;
+ case GdiBCTextOut:
+ ulSize = 0;
+ break;
+ case GdiBCExtTextOut:
+ ulSize = 0;
+ break;
+ case GdiBCSetBrushOrg:
+ ulSize = 0;
+ break;
+ case GdiBCExtSelClipRgn:
+ ulSize = 0;
+ break;
+ case GdiBCSelObj:
+ ulSize = sizeof(GDIBSOBJECT);
+ break;
+ case GdiBCDelRgn:
+ ulSize = sizeof(GDIBSOBJECT);
+ break;
+ case GdiBCDelObj:
+ ulSize = sizeof(GDIBSOBJECT);
+ break;
+ default:
+ return NULL;
+ }
+
+ /* Unsupported operation */
+ if (ulSize == 0) return NULL;
+
+ /* Check if the buffer is full */
+ if ((pTeb->GdiBatchCount >= GDI_BatchLimit) ||
+ ((pTeb->GdiTebBatch.Offset + ulSize) > GDIBATCHBUFSIZE))
+ {
+ /* Call win32k, the kernel will call NtGdiFlushUserBatch to flush
+ the current batch */
+ NtGdiFlush();
+ }
+
+ /* Get the head of the entry */
+ pHdr = (PVOID)((PUCHAR)pTeb->GdiTebBatch.Buffer + pTeb->GdiTebBatch.Offset);
+
+ /* Update Offset and batch count */
+ pTeb->GdiTebBatch.Offset += ulSize;
+ pTeb->GdiBatchCount++;
+
+ /* Fill in the core fields */
+ pHdr->Cmd = Cmd;
+ pHdr->Size = ulSize;
+
+ return pHdr;
+}
+
/* EOF */
Modified: trunk/reactos/dll/win32/gdi32/objects/dc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/objects/dc…
==============================================================================
--- trunk/reactos/dll/win32/gdi32/objects/dc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/objects/dc.c [iso-8859-1] Sat May 1 15:02:46 2010
@@ -1540,7 +1540,6 @@
PDC_ATTR pDc_Attr;
HGDIOBJ hOldObj = NULL;
UINT uType;
-// PTEB pTeb;
if(!GdiGetHandleUserData(hDC, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
{
@@ -1582,29 +1581,23 @@
case GDI_OBJECT_TYPE_FONT:
hOldObj = pDc_Attr->hlfntNew;
if (hOldObj == hGdiObj) return hOldObj;
-#if 0
+
pDc_Attr->ulDirty_ &= ~SLOW_WIDTHS;
pDc_Attr->ulDirty_ |= DIRTY_CHARSET;
pDc_Attr->hlfntNew = hGdiObj;
- pTeb = NtCurrentTeb();
- if (((pTeb->GdiTebBatch.HDC == 0) ||
- (pTeb->GdiTebBatch.HDC == hDC)) &&
- ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSOBJECT)) <=
GDIBATCHBUFSIZE) &&
- (!(pDc_Attr->ulDirty_ & DC_DIBSECTION)))
+
+ if (!(pDc_Attr->ulDirty_ & DC_DIBSECTION))
{
- PGDIBSOBJECT pgO = (PGDIBSOBJECT)(&pTeb->GdiTebBatch.Buffer[0] +
- pTeb->GdiTebBatch.Offset);
- pgO->gbHdr.Cmd = GdiBCSelObj;
- pgO->gbHdr.Size = sizeof(GDIBSOBJECT);
- pgO->hgdiobj = hGdiObj;
-
- pTeb->GdiTebBatch.Offset += sizeof(GDIBSOBJECT);
- pTeb->GdiTebBatch.HDC = hDC;
- pTeb->GdiBatchCount++;
- if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush();
- return hOldObj;
+ PGDIBSOBJECT pgO;
+
+ pgO = GdiAllocBatchCommand(hDC, GdiBCSelObj);
+ if (pgO)
+ {
+ pgO->hgdiobj = hGdiObj;
+ return hOldObj;
+ }
}
-#endif
+
// default for select object font
return NtGdiSelectFont(hDC, hGdiObj);
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] Sat May 1 15:02:46 2010
@@ -109,23 +109,14 @@
if ((GdiGetHandleUserData((HGDIOBJ) hRgn, GDI_OBJECT_TYPE_REGION, (PVOID)
&Rgn_Attr)) &&
( Rgn_Attr != NULL ))
{
- PTEB pTeb = NtCurrentTeb();
- if (pTeb->Win32ThreadInfo != NULL)
- {
- if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSOBJECT)) <= GDIBATCHBUFSIZE)
- {
- PGDIBSOBJECT pgO = (PGDIBSOBJECT)(&pTeb->GdiTebBatch.Buffer[0] +
- pTeb->GdiTebBatch.Offset);
- pgO->gbHdr.Cmd = GdiBCDelRgn;
- pgO->gbHdr.Size = sizeof(GDIBSOBJECT);
- pgO->hgdiobj = (HGDIOBJ)hRgn;
-
- pTeb->GdiTebBatch.Offset += sizeof(GDIBSOBJECT);
- pTeb->GdiBatchCount++;
- if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush();
- return TRUE;
- }
- }
+ PGDIBSOBJECT pgO;
+
+ pgO = GdiAllocBatchCommand(NULL, GdiBCDelRgn);
+ if (pgO)
+ {
+ pgO->hgdiobj = (HGDIOBJ)hRgn;
+ return TRUE;
+ }
}
return NtGdiDeleteObjectApp((HGDIOBJ) hRgn);
}