From b6af1f6baba4051e3ac36d9a6b6281ead91eec36 Mon Sep 17 00:00:00 2001 From: Jason Filby Date: Sun, 3 Jun 2001 10:47:29 +0000 Subject: [PATCH] Prevent mouse from interfering with GDI drawing svn path=/trunk/; revision=1939 --- reactos/subsys/win32k/eng/bitblt.c | 47 +++++++++++++++++++----- reactos/subsys/win32k/eng/copybits.c | 44 +++++++++++++++++++--- reactos/subsys/win32k/eng/lineto.c | 16 +++++--- reactos/subsys/win32k/eng/mouse.c | 55 ++++++++++++++++++++++++++-- reactos/subsys/win32k/eng/paint.c | 14 ++++++- reactos/subsys/win32k/eng/transblt.c | 19 ++++++++-- 6 files changed, 167 insertions(+), 28 deletions(-) diff --git a/reactos/subsys/win32k/eng/bitblt.c b/reactos/subsys/win32k/eng/bitblt.c index 6b08034cdbb..b18f3d3c244 100644 --- a/reactos/subsys/win32k/eng/bitblt.c +++ b/reactos/subsys/win32k/eng/bitblt.c @@ -35,6 +35,7 @@ BOOL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2) return(FALSE); } +INT abs(INT nm); BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, CLIPOBJ *ClipRegion, @@ -42,6 +43,7 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source, POINTL *SourcePoint, POINTL *MaskRect, BRUSHOBJ *Brush, POINTL *BrushOrigin, ROP4 rop4) { + BOOLEAN ret; BYTE clippingType; RECTL rclTmp; POINTL ptlTmp; @@ -56,6 +58,12 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source, SIZEL TempSize; if(Source != NULL) SourceGDI = AccessInternalObjectFromUserObject(Source); + if(Dest != NULL) DestGDI = AccessInternalObjectFromUserObject(Dest); + + MouseSafetyOnDrawStart(Source, SourceGDI, SourcePoint->x, SourcePoint->y, + (SourcePoint->x + abs(DestRect->right - DestRect->left)), + (SourcePoint->y + abs(DestRect->bottom - DestRect->top))); + MouseSafetyOnDrawStart(Dest, DestGDI, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); // If we don't have to do anything special, we can punt to DrvCopyBits // if it exists @@ -71,7 +79,6 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source, if(Dest->iType != STYPE_BITMAP) { // Destination surface is device managed - DestGDI = AccessInternalObjectFromUserObject(Dest); if (DestGDI->BitBlt!=NULL) { if (Source!=NULL) @@ -95,9 +102,14 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source, EngBitBlt(TempSurf, Source, NULL, NULL, ColorTranslation, &TempRect, SourcePoint, NULL, NULL, NULL, 0); } - return DestGDI->BitBlt(Dest, TempSurf, Mask, ClipRegion, - NULL, DestRect, &TempPoint, - MaskRect, Brush, BrushOrigin, rop4); + ret = DestGDI->BitBlt(Dest, TempSurf, Mask, ClipRegion, + NULL, DestRect, &TempPoint, + MaskRect, Brush, BrushOrigin, rop4); + + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + + return ret; } } @@ -107,17 +119,19 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source, if (SourceGDI->BitBlt!=NULL) { // Request the device driver to return the bitmap in a format compatible with the device - return SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion, - NULL, DestRect, SourcePoint, - MaskRect, Brush, BrushOrigin, rop4); + ret = SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion, + NULL, DestRect, SourcePoint, + MaskRect, Brush, BrushOrigin, rop4); + + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + + return ret; // Convert the surface from the driver into the required destination surface } } - DestGDI = AccessInternalObjectFromUserObject(Dest); - SourceGDI = AccessInternalObjectFromUserObject(Source); - // Determine clipping type if (ClipRegion == (CLIPOBJ *) NULL) { @@ -131,6 +145,10 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source, { case DC_TRIVIAL: CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation); + + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + return(TRUE); case DC_RECT: @@ -141,6 +159,9 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source, ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left; ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top; + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + return(TRUE); case DC_COMPLEX: @@ -168,8 +189,14 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source, } while(EnumMore); + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + return(TRUE); } + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + return(FALSE); } diff --git a/reactos/subsys/win32k/eng/copybits.c b/reactos/subsys/win32k/eng/copybits.c index 7edf7bb6770..deca91fbae9 100644 --- a/reactos/subsys/win32k/eng/copybits.c +++ b/reactos/subsys/win32k/eng/copybits.c @@ -52,6 +52,7 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source, CLIPOBJ *Clip, XLATEOBJ *ColorTranslation, RECTL *DestRect, POINTL *SourcePoint) { + BOOLEAN ret; SURFGDI *DestGDI, *SourceGDI; BYTE clippingType; RECTL rclTmp; @@ -59,6 +60,11 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source, RECT_ENUM RectEnum; BOOL EnumMore; + MouseSafetyOnDrawStart(Source, SourceGDI, SourcePoint->x, SourcePoint->y, + (SourcePoint->x + abs(DestRect->right - DestRect->left)), + (SourcePoint->y + abs(DestRect->bottom - DestRect->top))); + MouseSafetyOnDrawStart(Dest, DestGDI, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); + // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead, // mark the copy block function to be DrvCopyBits instead of the // GDI's copy bit function so as to remove clipping from the @@ -74,7 +80,12 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source, if (DestGDI->CopyBits!=NULL) { - return DestGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint); + ret = DestGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint); + + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + + return ret; } } @@ -85,14 +96,24 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source, if (SourceGDI->CopyBits!=NULL) { - return SourceGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint); + ret = SourceGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint); + + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + + return ret; } } // If CopyBits wasn't hooked, BitBlt must be - return EngBitBlt(Dest, Source, - NULL, Clip, ColorTranslation, DestRect, SourcePoint, - NULL, NULL, NULL, NULL); + ret = EngBitBlt(Dest, Source, + NULL, Clip, ColorTranslation, DestRect, SourcePoint, + NULL, NULL, NULL, NULL); + + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + + return ret; } // Determine clipping type @@ -114,6 +135,10 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source, { case DC_TRIVIAL: CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation); + + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + return(TRUE); case DC_RECT: @@ -125,6 +150,9 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source, CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, &rclTmp, &ptlTmp, Source->lDelta, ColorTranslation); + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + return(TRUE); case DC_COMPLEX: @@ -155,9 +183,15 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source, } while(EnumMore); + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + return(TRUE); } } + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + return FALSE; } diff --git a/reactos/subsys/win32k/eng/lineto.c b/reactos/subsys/win32k/eng/lineto.c index 326c662fbce..22e8fc61418 100644 --- a/reactos/subsys/win32k/eng/lineto.c +++ b/reactos/subsys/win32k/eng/lineto.c @@ -2,12 +2,11 @@ #include "objects.h" #include "../dib/dib.h" -// POSSIBLE FIXME: Switch X and Y's so that drawing a line doesn't try to draw from 150 to 50 (negative dx) - BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush, LONG x1, LONG y1, LONG x2, LONG y2, RECTL *RectBounds, MIX mix) { + BOOLEAN ret; SURFGDI *SurfGDI; LONG x, y, d, deltax, deltay, i, length, xchange, ychange, error, hx, vy; @@ -19,10 +18,14 @@ BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush, SurfGDI = AccessInternalObjectFromUserObject(Surface); + MouseSafetyOnDrawStart(Surface, SurfGDI, x1, y1, x2, y2); + if(Surface->iType!=STYPE_BITMAP) { // Call the driver's DrvLineTo - return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix); + ret = SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix); + MouseSafetyOnDrawEnd(Surface, SurfGDI); + return ret; } // Assign DIB functions according to bytes per pixel @@ -43,6 +46,8 @@ BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush, default: DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat, BitsPerFormat(Surface->iBitmapFormat)); + + MouseSafetyOnDrawEnd(Surface, SurfGDI); return FALSE; } @@ -75,8 +80,8 @@ BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush, vy = y1; } - if(y1==y2) { DIB_HLine(Surface, hx, hx + deltax, y1, Brush->iSolidColor); return TRUE; } - if(x1==x2) { DIB_VLine(Surface, x1, vy, vy + deltay, Brush->iSolidColor); return TRUE; } + if(y1==y2) { DIB_HLine(Surface, hx, hx + deltax, y1, Brush->iSolidColor); MouseSafetyOnDrawEnd(Surface, SurfGDI); return TRUE; } + if(x1==x2) { DIB_VLine(Surface, x1, vy, vy + deltay, Brush->iSolidColor); MouseSafetyOnDrawEnd(Surface, SurfGDI); return TRUE; } error=0; i=0; @@ -114,5 +119,6 @@ BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush, } } + MouseSafetyOnDrawEnd(Surface, SurfGDI); return TRUE; } diff --git a/reactos/subsys/win32k/eng/mouse.c b/reactos/subsys/win32k/eng/mouse.c index 73f7a5c1862..cdb4aee1edc 100644 --- a/reactos/subsys/win32k/eng/mouse.c +++ b/reactos/subsys/win32k/eng/mouse.c @@ -3,7 +3,53 @@ #include "..\..\services\input\include\mouse.h" #include "objects.h" +BOOLEAN SafetySwitch = FALSE, SafetySwitch2 = FALSE, MouseEnabled = FALSE; LONG mouse_x, mouse_y; +UINT mouse_width = 0, mouse_height = 0; + +INT MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2) +{ + RECTL MouseRect; + LONG tmp; + + if(SurfObj == NULL) return 0; + + if((SurfObj->iType != STYPE_DEVICE) || (MouseEnabled == FALSE)) return 0; + + if(HazardX1 > HazardX2) { tmp = HazardX2; HazardX2 = HazardX1; HazardX1 = tmp; } + if(HazardY1 > HazardY2) { tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp; } + + if( (mouse_x + mouse_width >= HazardX1) && (mouse_x <= HazardX2) && + (mouse_y + mouse_height >= HazardY1) && (mouse_y <= HazardY2) ) + { + SurfGDI->MovePointer(SurfObj, -1, -1, &MouseRect); + SafetySwitch = TRUE; + } + + // Mouse is not allowed to move if GDI is busy drawing + SafetySwitch2 = TRUE; + + return 1; +} + +INT MouseSafetyOnDrawEnd(PSURFOBJ SurfObj, PSURFGDI SurfGDI) +{ + RECTL MouseRect; + + if(SurfObj == NULL) return 0; + + if((SurfObj->iType != STYPE_DEVICE) || (MouseEnabled == FALSE)) return 0; + + if(SafetySwitch == TRUE) + { + SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect); + SafetySwitch = FALSE; + } + + SafetySwitch2 = FALSE; + + return 1; +} VOID MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount) { @@ -40,7 +86,8 @@ VOID MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount) if(mouse_x > 620) mouse_x = 620; if(mouse_y > 460) mouse_y = 460; - SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect); + if((SafetySwitch == FALSE) && (SafetySwitch2 == FALSE)) + SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect); } } @@ -111,6 +158,9 @@ void TestMouse() EngLineTo(SurfObj, NULL, &Brush, 1, 1, 1, 13, NULL, 0); EngLineTo(SurfObj, NULL, &Brush, 1, 13, 13, 1, NULL, 0); */ + mouse_width = 16; + mouse_height = 16; + // Draw transparent colored rectangle Brush.iSolidColor = 5; for (i = 0; i < 17; i++) @@ -147,6 +197,5 @@ void TestMouse() mouse_x = 50; mouse_y = 50; ConnectMouseClassDriver(); - - DbgPrint("OK\n"); + MouseEnabled = TRUE; } diff --git a/reactos/subsys/win32k/eng/paint.c b/reactos/subsys/win32k/eng/paint.c index 996861af96f..f9a25aad262 100644 --- a/reactos/subsys/win32k/eng/paint.c +++ b/reactos/subsys/win32k/eng/paint.c @@ -68,19 +68,29 @@ BOOL EngPaint(IN SURFOBJ *Surface, IN CLIPOBJ *ClipRegion, IN BRUSHOBJ *Brush, IN POINTL *BrushOrigin, IN MIX Mix) { + BOOLEAN ret; SURFGDI *SurfGDI; // Is the surface's Paint function hooked? SurfGDI = AccessInternalObjectFromUserObject(Surface); + // FIXME: Perform Mouse Safety on the given ClipRegion + // MouseSafetyOnDrawStart(Surface, SurfGDI, x1, y1, x2, y2); + if((Surface->iType!=STYPE_BITMAP) && (SurfGDI->Paint!=NULL)) { // Call the driver's DrvPaint - return SurfGDI->Paint(Surface, ClipRegion, Brush, BrushOrigin, Mix); + ret = SurfGDI->Paint(Surface, ClipRegion, Brush, BrushOrigin, Mix); + // MouseSafetyOnDrawEnd(Surface, SurfGDI); + return ret; } // FIXME: We only support a brush's solid color attribute - return(EngPaintRgn(Surface, ClipRegion, Brush->iSolidColor, Mix, NULL, BrushOrigin)); + ret = EngPaintRgn(Surface, ClipRegion, Brush->iSolidColor, Mix, NULL, BrushOrigin); + + // MouseSafetyOnDrawEnd(Surface, SurfGDI); + + return ret; } BOOL EngEraseSurface(SURFOBJ *Surface, RECTL *Rect, ULONG iColor) diff --git a/reactos/subsys/win32k/eng/transblt.c b/reactos/subsys/win32k/eng/transblt.c index 926bbcb6fd5..54e359e5cb0 100644 --- a/reactos/subsys/win32k/eng/transblt.c +++ b/reactos/subsys/win32k/eng/transblt.c @@ -20,12 +20,14 @@ BOOL EngTransparentBlt(PSURFOBJ Dest, PSURFOBJ Source, PRECTL DestRect, PRECTL SourceRect, ULONG TransparentColor, ULONG Reserved) { - PSURFGDI DestGDI = AccessInternalObjectFromUserObject(Dest); + PSURFGDI DestGDI = AccessInternalObjectFromUserObject(Dest), + SourceGDI = AccessInternalObjectFromUserObject(Source); HSURF hTemp; PSURFOBJ TempSurf; POINTL TempPoint, SourcePoint; RECTL TempRect; SIZEL TempSize; + BOOLEAN ret; LONG dx, dy, sx, sy; dx = abs(DestRect->right - DestRect->left); @@ -37,6 +39,9 @@ BOOL EngTransparentBlt(PSURFOBJ Dest, PSURFOBJ Source, if(sxleft, SourceRect->top, SourceRect->right, SourceRect->bottom); + MouseSafetyOnDrawStart(Dest, DestGDI, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); + if(DestGDI->TransparentBlt != NULL) { // The destination is device managed, therefore get the source into a format compatible surface @@ -59,11 +64,19 @@ BOOL EngTransparentBlt(PSURFOBJ Dest, PSURFOBJ Source, // 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); - return DestGDI->TransparentBlt(Dest, TempSurf, Clip, NULL, DestRect, SourceRect, - TransparentColor, Reserved); + ret = DestGDI->TransparentBlt(Dest, TempSurf, Clip, NULL, DestRect, SourceRect, + TransparentColor, Reserved); + + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + + return ret; } // Simulate a transparent blt + MouseSafetyOnDrawEnd(Source, SourceGDI); + MouseSafetyOnDrawEnd(Dest, DestGDI); + return TRUE; }