From a65f18771bd09fe386b331662b3d7cba33a8f39b Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 4 Jan 2013 11:02:43 +0000 Subject: [PATCH] [WIN32K] Implement DC_hSelectFont, use it from NtGdiSelectFont and GdiFlushUserBatch. Make sure plfnt is != NULL before dereferencing it in "TEXTOBJ_LockText" svn path=/trunk/; revision=58109 --- reactos/win32ss/gdi/ntgdi/dcobjs.c | 79 ++++++++++++++++++++++++++++ reactos/win32ss/gdi/ntgdi/font.c | 56 -------------------- reactos/win32ss/gdi/ntgdi/gdibatch.c | 38 +++++-------- reactos/win32ss/gdi/ntgdi/text.h | 7 ++- 4 files changed, 97 insertions(+), 83 deletions(-) diff --git a/reactos/win32ss/gdi/ntgdi/dcobjs.c b/reactos/win32ss/gdi/ntgdi/dcobjs.c index 85ef54bbcf9..be21fedb221 100644 --- a/reactos/win32ss/gdi/ntgdi/dcobjs.c +++ b/reactos/win32ss/gdi/ntgdi/dcobjs.c @@ -525,6 +525,85 @@ NtGdiSelectClipPath( return success; } +HFONT +NTAPI +DC_hSelectFont( + _In_ PDC pdc, + _In_ HFONT hlfntNew) +{ + PLFONT plfntNew; + HFONT hlfntOld; + + // Legacy crap that will die with font engine rewrite + if (!NT_SUCCESS(TextIntRealizeFont(hlfntNew, NULL))) + { + return NULL; + } + + /* Get the current selected font */ + hlfntOld = pdc->dclevel.plfnt->BaseObject.hHmgr; + + /* Check if a new font should be selected */ + if (hlfntNew != hlfntOld) + { + /* Lock the new font */ + plfntNew = LFONT_ShareLockFont(hlfntNew); + if (plfntNew) + { + /* Success, dereference the old font */ + LFONT_ShareUnlockFont(pdc->dclevel.plfnt); + + /* Select the new font */ + pdc->dclevel.plfnt = plfntNew; + pdc->pdcattr->hlfntNew = hlfntNew; + + /* Update dirty flags */ + pdc->pdcattr->ulDirty_ |= DIRTY_CHARSET; + pdc->pdcattr->ulDirty_ &= ~SLOW_WIDTHS; + } + else + { + /* Failed, restore old, return NULL */ + pdc->pdcattr->hlfntNew = hlfntOld; + hlfntOld = NULL; + } + } + + return hlfntOld; +} + +HFONT +APIENTRY +NtGdiSelectFont( + _In_ HDC hdc, + _In_ HFONT hfont) +{ + HFONT hfontOld; + PDC pdc; + + /* Check parameters */ + if ((hdc == NULL) || (hfont == NULL)) + { + return NULL; + } + + /* Lock the DC */ + pdc = DC_LockDc(hdc); + if (!pdc) + { + return NULL; + } + + /* Call the internal function */ + hfontOld = DC_hSelectFont(pdc, hfont); + + /* Unlock the DC */ + DC_UnlockDc(pdc); + + /* Return the previously selected font */ + return hfontOld; +} + HANDLE APIENTRY NtGdiGetDCObject(HDC hDC, INT ObjectType) diff --git a/reactos/win32ss/gdi/ntgdi/font.c b/reactos/win32ss/gdi/ntgdi/font.c index 3addda2b108..10bd73b1a8e 100644 --- a/reactos/win32ss/gdi/ntgdi/font.c +++ b/reactos/win32ss/gdi/ntgdi/font.c @@ -395,50 +395,6 @@ RealizeFontInit(HFONT hFont) return pTextObj; } -HFONT -FASTCALL -GreSelectFont( HDC hDC, HFONT hFont) -{ - PDC pdc; - PDC_ATTR pdcattr; - PTEXTOBJ pOrgFnt, pNewFnt = NULL; - HFONT hOrgFont = NULL; - - if (!hDC || !hFont) return NULL; - - pdc = DC_LockDc(hDC); - if (!pdc) - { - return NULL; - } - - if (NT_SUCCESS(TextIntRealizeFont((HFONT)hFont,NULL))) - { - /* LFONTOBJ use share and locking. */ - pNewFnt = TEXTOBJ_LockText(hFont); - pdcattr = pdc->pdcattr; - pOrgFnt = pdc->dclevel.plfnt; - if (pOrgFnt) - { - hOrgFont = pOrgFnt->BaseObject.hHmgr; - } - else - { - hOrgFont = pdcattr->hlfntNew; - } - if (pdc->dclevel.plfnt) LFONT_ShareUnlockFont(pdc->dclevel.plfnt); - if (pNewFnt) GDIOBJ_vReferenceObjectByPointer(&pNewFnt->BaseObject); - pdc->dclevel.plfnt = pNewFnt; - pdc->hlfntCur = hFont; - pdcattr->hlfntNew = hFont; - pdcattr->ulDirty_ |= DIRTY_CHARSET; - pdcattr->ulDirty_ &= ~SLOW_WIDTHS; - } - - if (pNewFnt) TEXTOBJ_UnlockText(pNewFnt); - DC_UnlockDc(pdc); - return hOrgFont; -} /** Functions ******************************************************************/ @@ -1122,17 +1078,5 @@ NtGdiHfontCreate( return hNewFont; } -/* - * @implemented - */ -HFONT -APIENTRY -NtGdiSelectFont( - IN HDC hDC, - IN HFONT hFont) -{ - return GreSelectFont(hDC, hFont); -} - /* EOF */ diff --git a/reactos/win32ss/gdi/ntgdi/gdibatch.c b/reactos/win32ss/gdi/ntgdi/gdibatch.c index f3f0a7f3d75..8602740318a 100644 --- a/reactos/win32ss/gdi/ntgdi/gdibatch.c +++ b/reactos/win32ss/gdi/ntgdi/gdibatch.c @@ -66,7 +66,6 @@ ULONG FASTCALL GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr) { - BOOL Hit = FALSE; ULONG Cmd = 0, Size = 0; PDC_ATTR pdcattr = NULL; @@ -82,27 +81,25 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr) } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Hit = TRUE; + DPRINT1("WARNING! GdiBatch Fault!\n"); + _SEH2_YIELD(return 0;) } _SEH2_END; - if (Hit) - { - DPRINT1("WARNING! GdiBatch Fault!\n"); - return 0; - } - - // FYI! The thread is approaching the end of sunset. switch(Cmd) { - case GdiBCPatBlt: // Highest pri first! + case GdiBCPatBlt: break; + case GdiBCPolyPatBlt: break; + case GdiBCTextOut: break; + case GdiBCExtTextOut: break; + case GdiBCSetBrushOrg: { PGDIBSSETBRHORG pgSBO; @@ -112,40 +109,31 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr) DC_vSetBrushOrigin(dc, pgSBO->ptlBrushOrigin.x, pgSBO->ptlBrushOrigin.y); break; } + case GdiBCExtSelClipRgn: break; + case GdiBCSelObj: { PGDIBSOBJECT pgO; - PTEXTOBJ pNewFnt = NULL; if (!dc) break; pgO = (PGDIBSOBJECT) pHdr; - if (NT_SUCCESS(TextIntRealizeFont((HFONT)pgO->hgdiobj,NULL))) - { - /* LFONTOBJ use share and locking. */ - pNewFnt = TEXTOBJ_LockText(pgO->hgdiobj); - - if (dc->dclevel.plfnt) LFONT_ShareUnlockFont(dc->dclevel.plfnt); - if (pNewFnt) GDIOBJ_vReferenceObjectByPointer(&pNewFnt->BaseObject); - dc->dclevel.plfnt = pNewFnt; - dc->hlfntCur = pgO->hgdiobj; - pdcattr->hlfntNew = pgO->hgdiobj; - pdcattr->ulDirty_ |= DIRTY_CHARSET; - pdcattr->ulDirty_ &= ~SLOW_WIDTHS; - } - if (pNewFnt) TEXTOBJ_UnlockText(pNewFnt); + DC_hSelectFont(dc, (HFONT)pgO->hgdiobj); break; } + case GdiBCDelRgn: DPRINT("Delete Region Object!\n"); + /* Fall through */ case GdiBCDelObj: { PGDIBSOBJECT pgO = (PGDIBSOBJECT) pHdr; GreDeleteObject( pgO->hgdiobj ); break; } + default: break; } diff --git a/reactos/win32ss/gdi/ntgdi/text.h b/reactos/win32ss/gdi/ntgdi/text.h index 20bfbbda0c3..2fd1bbe4f24 100644 --- a/reactos/win32ss/gdi/ntgdi/text.h +++ b/reactos/win32ss/gdi/ntgdi/text.h @@ -85,8 +85,11 @@ FORCEINLINE TEXTOBJ_LockText(HFONT hfont) { PLFONT plfnt = LFONT_ShareLockFont(hfont); - KeEnterCriticalRegion(); - ExAcquirePushLockExclusive(&plfnt->lock); + if (plfnt != 0) + { + KeEnterCriticalRegion(); + ExAcquirePushLockExclusive(&plfnt->lock); + } return plfnt; }