diff --git a/reactos/dll/win32/gdi32/include/gdi32p.h b/reactos/dll/win32/gdi32/include/gdi32p.h index 38a3330d130..5fc21d94337 100644 --- a/reactos/dll/win32/gdi32/include/gdi32p.h +++ b/reactos/dll/win32/gdi32/include/gdi32p.h @@ -112,6 +112,10 @@ NewTextMetricExW2A( NEWTEXTMETRICEXW *tmw ); +BOOL +FASTCALL +DeleteRegion( HRGN ); + BOOL GdiIsHandleValid(HGDIOBJ hGdiObj); diff --git a/reactos/dll/win32/gdi32/objects/dc.c b/reactos/dll/win32/gdi32/objects/dc.c index 496be2f9334..3b6436d09a7 100644 --- a/reactos/dll/win32/gdi32/objects/dc.c +++ b/reactos/dll/win32/gdi32/objects/dc.c @@ -284,7 +284,7 @@ STDCALL DeleteObject(HGDIOBJ hObject) { UINT Type = 0; - + /* From Wine: DeleteObject does not SetLastError() on a null object */ if(!hObject) return FALSE; @@ -308,6 +308,8 @@ DeleteObject(HGDIOBJ hObject) return DeleteDC((HDC) hObject); case GDI_OBJECT_TYPE_COLORSPACE: return NtGdiDeleteColorSpace((HCOLORSPACE) hObject); + case GDI_OBJECT_TYPE_REGION: + return DeleteRegion((HRGN) hObject); #if 0 case GDI_OBJECT_TYPE_METADC: return MFDRV_DeleteObject( hObject ); @@ -318,12 +320,42 @@ DeleteObject(HGDIOBJ hObject) return EMFDRV_DeleteObject( hObject ); } #endif - case GDI_OBJECT_TYPE_REGION: + case GDI_OBJECT_TYPE_FONT: + break; + case GDI_OBJECT_TYPE_BRUSH: case GDI_OBJECT_TYPE_EXTPEN: case GDI_OBJECT_TYPE_PEN: - case GDI_OBJECT_TYPE_FONT: + { +#if 0 + PBRUSH_ATTR Brh_Attr; + PTEB pTeb; + + if ((!GdiGetHandleUserData(hObject, (PVOID) &Brh_Attr)) || + (Brh_Attr == NULL) ) break; + + pTeb = NtCurrentTeb(); + + if (pTeb->Win32ThreadInfo == NULL) break; + + if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSOBJECT)) <= GDIBATCHBUFSIZE) + { + PGDIBSOBJECT pgO = (PGDIBSOBJECT)(&pTeb->GdiTebBatch.Buffer[0] + + pTeb->GdiTebBatch.Offset); + pgO->gbHdr.Cmd = GdiBCDelObj; + pgO->gbHdr.Size = sizeof(GDIBSOBJECT); + pgO->hgdiobj = hObject; + + pTeb->GdiTebBatch.Offset += sizeof(GDIBSSETBRHORG); + pTeb->GdiBatchCount++; + if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush(); + return TRUE; + } +#endif + break; + } case GDI_OBJECT_TYPE_BITMAP: + default: break; } return NtGdiDeleteObjectApp(hObject); diff --git a/reactos/dll/win32/gdi32/objects/region.c b/reactos/dll/win32/gdi32/objects/region.c index 650316f2ac8..23c5cead6a0 100644 --- a/reactos/dll/win32/gdi32/objects/region.c +++ b/reactos/dll/win32/gdi32/objects/region.c @@ -76,3 +76,40 @@ CreateRectRgnIndirect( return CreateRectRgn(prc->left, prc->top, prc->right, prc->bottom); } + +/* + * I thought it was okay to have this in DeleteObject but~ Speed. (jt) + */ +BOOL +FASTCALL +DeleteRegion( HRGN hRgn ) +{ +#if 0 + PREGION_ATTR Rgn_Attr; + + if ((GdiGetHandleUserData((HGDIOBJ) hRgn, (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(GDIBSSETBRHORG); + pTeb->GdiBatchCount++; + if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush(); + return TRUE; + } + } + } +#endif + return NtGdiDeleteObjectApp((HGDIOBJ) hRgn); +} + diff --git a/reactos/subsystems/win32/win32k/objects/gdibatch.c b/reactos/subsystems/win32/win32k/objects/gdibatch.c index 537042fdfa9..08f664f9fa5 100644 --- a/reactos/subsystems/win32/win32k/objects/gdibatch.c +++ b/reactos/subsystems/win32/win32k/objects/gdibatch.c @@ -42,9 +42,12 @@ GdiFlushUserBatch(HDC hDC, PGDIBATCHHDR pHdr) case GdiBCSelObj: break; case GdiBCDelObj: - break; case GdiBCDelRgn: + { + PGDIBSOBJECT pgO = (PGDIBSOBJECT) pHdr; + NtGdiDeleteObject( pgO->hgdiobj ); break; + } default: DC_UnlockDc(dc); return 0; @@ -62,6 +65,8 @@ VOID APIENTRY NtGdiFlush(VOID) { + // Hack! FIXME! + NtYieldExecution(); // Force thread to sunset and run the flush. UNIMPLEMENTED; } @@ -82,7 +87,11 @@ NtGdiFlushUserBatch(VOID) if( (GdiBatchCount > 0) && (GdiBatchCount <= GDIBATCHBUFSIZE)) { HDC hDC = (HDC) pTeb->GdiTebBatch.HDC; - if (hDC) +// +// If hDC is zero and the buffer fills up with delete objects we need to run +// anyway. So, hard code to the system batch limit. +// + if ((hDC) || (GdiBatchCount >= GDI_BATCH_LIMIT)) { PULONG pHdr = &pTeb->GdiTebBatch.Buffer[0]; // No need to init anything, just go!