Serialize access to display driver. Fixes serious display corruption

with the VGA driver: drawing function starts and sets up VGA registers,
mouse moves and pointer needs to be redrawn for which VGA registers
are changed, then drawing function continues with wrong registers

svn path=/trunk/; revision=7688
This commit is contained in:
Gé van Geldorp 2004-01-16 19:32:00 +00:00
parent 0fd869efa8
commit 660a7812d3
16 changed files with 78 additions and 27 deletions

View file

@ -41,7 +41,7 @@ int STDCALL DIB_GetDIBImageBytes (INT width, INT height, INT depth);
INT FASTCALL DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse);
INT STDCALL BITMAP_GetObject(BITMAPOBJ * bmp, INT count, LPVOID buffer);
BOOL FASTCALL Bitmap_InternalDelete( PBITMAPOBJ pBmp );
HBITMAP FASTCALL BitmapToSurf(PBITMAPOBJ BitmapObj);
HBITMAP FASTCALL BitmapToSurf(PBITMAPOBJ BitmapObj, HDEV GDIDevice);
/* User Entry Points */
BOOL

View file

@ -84,6 +84,7 @@ typedef struct _DC
PGDIINFO GDIInfo;
PDEVINFO DevInfo;
HSURF Surface;
HDEV GDIDevice;
DRIVER_FUNCTIONS DriverFunctions;
UNICODE_STRING DriverName;
@ -115,6 +116,7 @@ typedef struct
DEVINFO DevInfo;
DRIVER_FUNCTIONS DriverFunctions;
PFILE_OBJECT VideoFileObject;
FAST_MUTEX DriverLock;
} GDIDEVICE;
/* Internal functions */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: bitblt.c,v 1.38 2004/01/11 19:52:27 gvg Exp $
/* $Id: bitblt.c,v 1.39 2004/01/16 19:32:00 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -472,9 +472,11 @@ IntEngBitBlt(SURFOBJ *DestObj,
/* Call the driver's DrvBitBlt if available */
if (NULL != DestGDI->BitBlt)
{
ExAcquireFastMutex(DestGDI->DriverLock);
ret = DestGDI->BitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
&OutputRect, &InputPoint, MaskOrigin, Brush, BrushOrigin,
Rop4);
ExReleaseFastMutex(DestGDI->DriverLock);
}
if (! ret)
@ -788,8 +790,10 @@ IntEngStretchBlt(SURFOBJ *DestObj,
/* Drv->StretchBlt (look at http://www.osr.com/ddk/graphics/ddifncs_3ew7.htm )
SURFOBJ *psoMask // optional, if it exists, then rop4=0xCCAA, otherwise rop4=0xCCCC */
// FIXME: MaskOrigin is always NULL !
ExAcquireFastMutex(DestGDI->DriverLock);
ret = DestGDI->StretchBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
&ca, BrushOrigin, &OutputRect, &InputRect, NULL, Mode);
ExReleaseFastMutex(DestGDI->DriverLock);
}
if (! ret)
@ -908,6 +912,7 @@ EngMaskBitBlt(SURFOBJ *DestObj,
unsigned i;
POINTL Pt;
ULONG Direction;
SURFGDI* DestGDI;
if (NULL != SourcePoint)
{
@ -924,8 +929,11 @@ EngMaskBitBlt(SURFOBJ *DestObj,
InputRect.bottom = DestRect->bottom - DestRect->top;
}
DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj);
ExAcquireFastMutex(DestGDI->DriverLock);
if (! IntEngEnter(&EnterLeaveSource, NULL, &InputRect, TRUE, &Translate, &InputObj))
{
ExReleaseFastMutex(DestGDI->DriverLock);
return FALSE;
}
@ -981,12 +989,14 @@ EngMaskBitBlt(SURFOBJ *DestObj,
if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
{
IntEngLeave(&EnterLeaveSource);
ExReleaseFastMutex(DestGDI->DriverLock);
return TRUE;
}
if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj))
{
IntEngLeave(&EnterLeaveSource);
ExReleaseFastMutex(DestGDI->DriverLock);
return FALSE;
}
@ -1081,6 +1091,8 @@ EngMaskBitBlt(SURFOBJ *DestObj,
IntEngLeave(&EnterLeaveDest);
IntEngLeave(&EnterLeaveSource);
ExReleaseFastMutex(DestGDI->DriverLock);
/* Dummy BitBlt to let driver know that something has changed.
0x00AA0029 is the Rop for D (no-op) */
IntEngBitBlt(DestObj, NULL, Mask, ClipRegion, DestColorTranslation,

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: copybits.c,v 1.19 2003/12/31 16:06:48 weiden Exp $
/* $Id: copybits.c,v 1.20 2004/01/16 19:32:00 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -75,7 +75,9 @@ EngCopyBits(SURFOBJ *Dest,
if (DestGDI->CopyBits!=NULL)
{
ExAcquireFastMutex(DestGDI->DriverLock);
ret = DestGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
ExReleaseFastMutex(DestGDI->DriverLock);
MouseSafetyOnDrawEnd(Source, SourceGDI);
MouseSafetyOnDrawEnd(Dest, DestGDI);
@ -91,7 +93,9 @@ EngCopyBits(SURFOBJ *Dest,
if (SourceGDI->CopyBits!=NULL)
{
ExAcquireFastMutex(DestGDI->DriverLock);
ret = SourceGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
ExReleaseFastMutex(DestGDI->DriverLock);
MouseSafetyOnDrawEnd(Source, SourceGDI);
MouseSafetyOnDrawEnd(Dest, DestGDI);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: lineto.c,v 1.28 2003/12/31 16:06:48 weiden Exp $
* $Id: lineto.c,v 1.29 2004/01/16 19:32:00 gvg Exp $
*/
#include <ddk/winddi.h>
@ -501,7 +501,7 @@ IntEngLineTo(SURFOBJ *DestSurf,
{
BOOLEAN ret;
SURFGDI *SurfGDI;
RECTL b;
RECTL b;
if (Brush->logbrush.lbStyle == BS_NULL)
return TRUE;
@ -510,18 +510,20 @@ RECTL b;
ret = FALSE;
SurfGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestSurf);
b.left = min(x1, x2);
b.right = max(x1, x2);
b.top = min(y1, y2);
b.bottom = max(y1, y2);
if (b.left == b.right) b.right++;
if (b.top == b.bottom) b.bottom++;
b.left = min(x1, x2);
b.right = max(x1, x2);
b.top = min(y1, y2);
b.bottom = max(y1, y2);
if (b.left == b.right) b.right++;
if (b.top == b.bottom) b.bottom++;
MouseSafetyOnDrawStart(DestSurf, SurfGDI, x1, y1, x2, y2);
if (NULL != SurfGDI->LineTo)
{
/* Call the driver's DrvLineTo */
ExAcquireFastMutex(SurfGDI->DriverLock);
ret = SurfGDI->LineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, /*RectBounds*/&b, mix);
ExReleaseFastMutex(SurfGDI->DriverLock);
}
#if 0

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: mouse.c,v 1.54 2004/01/16 15:39:28 gvg Exp $
/* $Id: mouse.c,v 1.55 2004/01/16 19:32:00 gvg Exp $
*
* PROJECT: ReactOS kernel
* PURPOSE: Mouse
@ -150,7 +150,9 @@ MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1,
return FALSE;
}
CurInfo->SafetySwitch = TRUE;
ExAcquireFastMutex(SurfGDI->DriverLock);
SurfGDI->MovePointer(SurfObj, -1, -1, NULL);
ExReleaseFastMutex(SurfGDI->DriverLock);
ExReleaseFastMutex(&CurInfo->CursorMutex);
}
@ -218,7 +220,9 @@ MouseSafetyOnDrawEnd(PSURFOBJ SurfObj, PSURFGDI SurfGDI)
ObDereferenceObject(InputWindowStation);
return FALSE;
}
ExAcquireFastMutex(SurfGDI->DriverLock);
SurfGDI->MovePointer(SurfObj, CurInfo->x, CurInfo->y, &PointerRect);
ExReleaseFastMutex(SurfGDI->DriverLock);
SetPointerRect(CurInfo, &PointerRect);
CurInfo->SafetySwitch = FALSE;
}
@ -272,7 +276,9 @@ MouseMoveCursor(LONG X, LONG Y)
if(CurInfo->Enabled)
{
ExAcquireFastMutex(&CurInfo->CursorMutex);
ExAcquireFastMutex(SurfGDI->DriverLock);
SurfGDI->MovePointer(SurfObj, CurInfo->x, CurInfo->y, &PointerRect);
ExReleaseFastMutex(SurfGDI->DriverLock);
SetPointerRect(CurInfo, &PointerRect);
ExReleaseFastMutex(&CurInfo->CursorMutex);
}
@ -431,7 +437,9 @@ MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
((mouse_ox != CurInfo->x) || (mouse_oy != CurInfo->y)))
{
ExAcquireFastMutex(&CurInfo->CursorMutex);
ExAcquireFastMutex(SurfGDI->DriverLock);
SurfGDI->MovePointer(SurfObj, CurInfo->x, CurInfo->y, &PointerRect);
ExReleaseFastMutex(SurfGDI->DriverLock);
SetPointerRect(CurInfo, &PointerRect);
ExReleaseFastMutex(&CurInfo->CursorMutex);
mouse_cx = 0;
@ -459,7 +467,9 @@ MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
((mouse_ox != CurInfo->x) || (mouse_oy != CurInfo->y)))
{
ExAcquireFastMutex(&CurInfo->CursorMutex);
ExAcquireFastMutex(SurfGDI->DriverLock);
SurfGDI->MovePointer(SurfObj, CurInfo->x, CurInfo->y, &PointerRect);
ExReleaseFastMutex(SurfGDI->DriverLock);
SetPointerRect(CurInfo, &PointerRect);
ExReleaseFastMutex(&CurInfo->CursorMutex);
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: objects.h,v 1.24 2003/12/21 10:27:10 navaraf Exp $
/* $Id: objects.h,v 1.25 2004/01/16 19:32:00 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -195,7 +195,8 @@ typedef struct _SURFGDI {
PFN_DIB_StretchBlt DIB_StretchBlt;
/* misc */
ULONG PointerStatus;
ULONG PointerStatus;
PFAST_MUTEX DriverLock;
} SURFGDI;
typedef struct _XFORMGDI {

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: paint.c,v 1.16 2003/12/31 16:06:48 weiden Exp $
/* $Id: paint.c,v 1.17 2004/01/16 19:32:00 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -141,7 +141,9 @@ IntEngPaint(IN SURFOBJ *Surface,
ClipRegion->rclBounds.top, ClipRegion->rclBounds.right,
ClipRegion->rclBounds.bottom);
ExAcquireFastMutex(SurfGDI->DriverLock);
ret = SurfGDI->Paint(Surface, ClipRegion, Brush, BrushOrigin, Mix);
ExReleaseFastMutex(SurfGDI->DriverLock);
MouseSafetyOnDrawEnd(Surface, SurfGDI);
return ret;
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: surface.c,v 1.29 2003/12/21 10:27:10 navaraf Exp $
/* $Id: surface.c,v 1.30 2004/01/16 19:32:00 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -464,6 +464,8 @@ EngAssociateSurface(IN HSURF Surface,
SurfGDI->MovePointer = Device->DriverFunctions.MovePointer;
SurfGDI->SetPointerShape = (PFN_SetPointerShape)Device->DriverFunctions.SetPointerShape;
SurfGDI->DriverLock = &Device->DriverLock;
return TRUE;
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: transblt.c,v 1.9 2003/05/18 17:16:17 ea Exp $
/* $Id: transblt.c,v 1.10 2004/01/16 19:32:00 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -96,8 +96,10 @@ EngTransparentBlt(PSURFOBJ Dest,
// FIXME: Skip creating a TempSurf if we have the same BPP and palette
EngBitBlt(TempSurf, Source, NULL, NULL, ColorTranslation, &TempRect, &SourcePoint, NULL, NULL, NULL, 0);
ExAcquireFastMutex(DestGDI->DriverLock);
ret = DestGDI->TransparentBlt(Dest, TempSurf, Clip, NULL, DestRect, SourceRect,
TransparentColor, Reserved);
ExReleaseFastMutex(DestGDI->DriverLock);
MouseSafetyOnDrawEnd(Source, SourceGDI);
MouseSafetyOnDrawEnd(Dest, DestGDI);

View file

@ -136,7 +136,7 @@ HPenToBrushObj ( BRUSHOBJ *brush, HPEN hpen );
HBITMAP
FASTCALL
BitmapToSurf ( PBITMAPOBJ BitmapObj );
BitmapToSurf ( PBITMAPOBJ BitmapObj, HDEV GDIDevice );
#endif /* _WIN32K_OBJECT_H */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: color.c,v 1.32 2003/12/22 15:30:21 navaraf Exp $ */
/* $Id: color.c,v 1.33 2004/01/16 19:32:00 gvg Exp $ */
// FIXME: Use PXLATEOBJ logicalToSystem instead of int *mapping
@ -333,7 +333,9 @@ UINT STDCALL NtGdiRealizePalette(HDC hDC)
} else {
if(SurfGDI->SetPalette)
{
ExAcquireFastMutex(SurfGDI->DriverLock);
success = SurfGDI->SetPalette(dc->PDev, sysPtr, 0, 0, sysGDI->NumColors);
ExReleaseFastMutex(SurfGDI->DriverLock);
}
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: cursoricon.c,v 1.42 2004/01/16 15:39:28 gvg Exp $ */
/* $Id: cursoricon.c,v 1.43 2004/01/16 19:32:00 gvg Exp $ */
#undef WIN32_LEAN_AND_MEAN
@ -141,6 +141,7 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, BOOL Fo
if(!NewCursor && (CurInfo->CurrentCursorObject || ForceChange))
{
ExAcquireFastMutex(SurfGDI->DriverLock);
SurfGDI->PointerStatus = SurfGDI->SetPointerShape(SurfObj, NULL, NULL, NULL,
0,
0,
@ -148,6 +149,7 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, BOOL Fo
CurInfo->y,
&PointerRect,
SPS_CHANGE);
ExReleaseFastMutex(SurfGDI->DriverLock);
SetPointerRect(CurInfo, &PointerRect);
CurInfo->CurrentCursorObject = NewCursor; /* i.e. CurrentCursorObject = NULL */
@ -216,6 +218,7 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, BOOL Fo
CurInfo->CurrentCursorObject = NULL;
}
ExAcquireFastMutex(SurfGDI->DriverLock);
SurfGDI->PointerStatus = SurfGDI->SetPointerShape(SurfObj, soMask, soColor, XlateObj,
NewCursor->IconInfo.xHotspot,
NewCursor->IconInfo.yHotspot,
@ -223,6 +226,7 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, BOOL Fo
CurInfo->y,
&PointerRect,
SPS_CHANGE);
ExReleaseFastMutex(SurfGDI->DriverLock);
SetPointerRect(CurInfo, &PointerRect);
if(hMask)

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: dc.c,v 1.116 2004/01/05 15:43:55 weiden Exp $
/* $Id: dc.c,v 1.117 2004/01/16 19:32:00 gvg Exp $
*
* DC.C - Device context functions
*
@ -213,8 +213,9 @@ NtGdiCreateCompatableDC(HDC hDC)
NewDC->w.flags = DC_MEMORY;
NewDC->w.hBitmap = hBitmap;
NewDC->w.hFirstBitmap = hBitmap;
NewDC->GDIDevice = OrigDC->GDIDevice;
pb = BITMAPOBJ_LockBitmap(hBitmap);
NewDC->Surface = BitmapToSurf(pb);
NewDC->Surface = BitmapToSurf(pb, NewDC->GDIDevice);
BITMAPOBJ_UnlockBitmap(hBitmap);
NewDC->w.hPalette = OrigDC->w.hPalette;
@ -473,6 +474,8 @@ IntCreatePrimarySurface()
BOOL GotDriver;
BOOL DoDefault;
ExInitializeFastMutex(&PrimarySurface.DriverLock);
/* Open the miniport driver */
if ((PrimarySurface.VideoFileObject = DRIVER_FindMPDriver(L"DISPLAY")) == NULL)
{
@ -710,6 +713,7 @@ IntGdiCreateDC(PUNICODE_STRING Driver,
sizeof(NewDC->FillPatternSurfaces));
NewDC->PDev = PrimarySurface.PDev;
NewDC->Surface = PrimarySurface.Handle;
NewDC->GDIDevice = &PrimarySurface;
NewDC->DriverFunctions = PrimarySurface.DriverFunctions;
NewDC->DMW.dmSize = sizeof(NewDC->DMW);
@ -1779,7 +1783,7 @@ NtGdiSelectObject(HDC hDC, HGDIOBJ hGDIObj)
/* Release the old bitmap, lock the new one and convert it to a SURF */
EngDeleteSurface(dc->Surface);
dc->w.hBitmap = hGDIObj;
dc->Surface = BitmapToSurf(pb);
dc->Surface = BitmapToSurf(pb, dc->GDIDevice);
// if we're working with a DIB, get the palette [fixme: only create if the selected palette is null]
if(pb->dib)

View file

@ -1,5 +1,5 @@
/*
* $Id: dib.c,v 1.39 2003/12/20 14:51:41 navaraf Exp $
* $Id: dib.c,v 1.40 2004/01/16 19:32:00 gvg Exp $
*
* ReactOS W32 Subsystem
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
@ -131,7 +131,7 @@ NtGdiSetDIBits(
// lpRGB = &bmi->bmiColors[0];
// Create a temporary surface for the destination bitmap
DestBitmap = BitmapToSurf(bitmap);
DestBitmap = BitmapToSurf(bitmap, dc->GDIDevice);
DestSurf = (PSURFOBJ) AccessUserObject( (ULONG)DestBitmap );
DestGDI = (PSURFGDI) AccessInternalObject( (ULONG)DestBitmap );

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: objconv.c,v 1.13 2003/09/26 20:58:06 gvg Exp $ */
/* $Id: objconv.c,v 1.14 2004/01/16 19:32:00 gvg Exp $ */
#undef WIN32_LEAN_AND_MEAN
#include <windows.h>
@ -67,7 +67,7 @@ HPenToBrushObj ( BRUSHOBJ *brush, HPEN hpen )
return brush;
}
HBITMAP FASTCALL BitmapToSurf(PBITMAPOBJ BitmapObj)
HBITMAP FASTCALL BitmapToSurf(PBITMAPOBJ BitmapObj, HDEV GDIDevice)
{
HBITMAP BitmapHandle;
@ -84,6 +84,10 @@ HBITMAP FASTCALL BitmapToSurf(PBITMAPOBJ BitmapObj)
BitmapFormat(BitmapObj->bitmap.bmBitsPixel, BI_RGB),
0, BitmapObj->bitmap.bmBits);
}
if (NULL != BitmapHandle)
{
EngAssociateSurface(BitmapHandle, GDIDevice, 0);
}
return BitmapHandle;
}