Prevent mouse from interfering with GDI drawing

svn path=/trunk/; revision=1939
This commit is contained in:
Jason Filby 2001-06-03 10:47:29 +00:00
parent c3b862d61d
commit b6af1f6bab
6 changed files with 167 additions and 28 deletions

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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)

View file

@ -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(sx<dx) dx = sx;
if(sy<dy) dy = sy;
MouseSafetyOnDrawStart(Source, SourceGDI, SourceRect->left, 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;
}