Work on mouse pointer implementation.

svn path=/trunk/; revision=7864
This commit is contained in:
Filip Navara 2004-01-24 17:42:56 +00:00
parent ed4bb6a2cd
commit db0f9b9ba4
4 changed files with 345 additions and 3 deletions

View file

@ -31,7 +31,7 @@ static DRVFN DrvFunctionTable[] =
{INDEX_DrvGetModes, (PFN)DrvGetModes},
{INDEX_DrvSetPalette, (PFN)DrvSetPalette},
{INDEX_DrvSetPointerShape, (PFN)DrvSetPointerShape},
{INDEX_DrvMovePointer, (PFN)DrvMovePointer},
{INDEX_DrvMovePointer, (PFN)DrvMovePointer}
};
/*

View file

@ -26,6 +26,8 @@
#include <ddk/winddi.h>
#include <ddk/ntddvdeo.h>
#define EXPERIMENTAL_MOUSE_CURSOR_SUPPORT
typedef struct _PDEV
{
HANDLE hDriver;
@ -43,6 +45,16 @@ typedef struct _PDEV
PVOID ScreenPtr;
HPALETTE DefaultPalette;
PALETTEENTRY *PaletteEntries;
#ifdef EXPERIMENTAL_MOUSE_CURSOR_SUPPORT
VIDEO_POINTER_ATTRIBUTES PointerAttributes;
HSURF PointerColorSurface;
HSURF PointerMaskSurface;
HSURF PointerSaveSurface;
XLATEOBJ *XlateObject;
POINTL HotSpot;
CLIPOBJ *ScreenClipObj;
#endif
} PDEV, *PPDEV;
#define DEVICE_NAME L"framebuf"

View file

@ -20,6 +20,8 @@
#include "framebuf.h"
#ifndef EXPERIMENTAL_MOUSE_CURSOR_SUPPORT
/*
* DrvSetPointerShape
*
@ -64,3 +66,313 @@ DrvMovePointer(
{
}
#else
VOID FASTCALL
IntHideMousePointer(PPDEV ppdev)
{
if (ppdev->PointerAttributes.Enable == FALSE)
{
return;
}
ppdev->PointerAttributes.Enable = FALSE;
if (ppdev->PointerSaveSurface != NULL)
{
RECTL DestRect;
POINTL SrcPoint;
SURFOBJ *SaveSurface;
SURFOBJ *DestSurface;
SURFOBJ *MaskSurface;
DestRect.left = max(ppdev->PointerAttributes.Column, 0);
DestRect.top = max(ppdev->PointerAttributes.Row, 0);
DestRect.right = min(
ppdev->PointerAttributes.Column + ppdev->PointerAttributes.Width,
ppdev->ScreenWidth - 1);
DestRect.bottom = min(
ppdev->PointerAttributes.Row + ppdev->PointerAttributes.Height,
ppdev->ScreenHeight - 1);
SrcPoint.x = max(-ppdev->PointerAttributes.Column, 0);
SrcPoint.y = max(-ppdev->PointerAttributes.Row, 0);
SaveSurface = EngLockSurface(ppdev->PointerSaveSurface);
DestSurface = EngLockSurface(ppdev->hSurfEng);
MaskSurface = EngLockSurface(ppdev->PointerMaskSurface);
EngBitBlt(DestSurface, SaveSurface, MaskSurface, NULL, NULL,
&DestRect, &SrcPoint, &SrcPoint, NULL, NULL, SRCCOPY);
EngUnlockSurface(MaskSurface);
EngUnlockSurface(DestSurface);
EngUnlockSurface(SaveSurface);
}
}
VOID FASTCALL
IntShowMousePointer(PPDEV ppdev)
{
if (ppdev->PointerAttributes.Enable == TRUE)
{
return;
}
ppdev->PointerAttributes.Enable = TRUE;
/*
* Copy the pixels under the cursor to temporary surface.
*/
if (ppdev->PointerSaveSurface != NULL)
{
RECTL DestRect;
POINTL SrcPoint;
SURFOBJ *SaveSurface;
SURFOBJ *DestSurface;
SrcPoint.x = max(ppdev->PointerAttributes.Column, 0);
SrcPoint.y = max(ppdev->PointerAttributes.Row, 0);
DestRect.left = SrcPoint.x - ppdev->PointerAttributes.Column;
DestRect.top = SrcPoint.y - ppdev->PointerAttributes.Row;
DestRect.right = min(
ppdev->PointerAttributes.Width,
ppdev->ScreenWidth - ppdev->PointerAttributes.Column - 1);
DestRect.bottom = min(
ppdev->PointerAttributes.Height,
ppdev->ScreenHeight - ppdev->PointerAttributes.Row - 1);
SaveSurface = EngLockSurface(ppdev->PointerSaveSurface);
DestSurface = EngLockSurface(ppdev->hSurfEng);
EngBitBlt(SaveSurface, DestSurface, NULL, NULL, NULL,
&DestRect, &SrcPoint, NULL, NULL, NULL, SRCCOPY);
EngUnlockSurface(DestSurface);
EngUnlockSurface(SaveSurface);
}
/*
* Blit the cursor on the screen.
*/
{
RECTL DestRect;
POINTL SrcPoint;
SURFOBJ *DestSurf;
SURFOBJ *ColorSurf;
SURFOBJ *MaskSurf;
DestRect.left = max(ppdev->PointerAttributes.Column, 0);
DestRect.top = max(ppdev->PointerAttributes.Row, 0);
DestRect.right = min(
ppdev->PointerAttributes.Column + ppdev->PointerAttributes.Width,
ppdev->ScreenWidth - 1);
DestRect.bottom = min(
ppdev->PointerAttributes.Row + ppdev->PointerAttributes.Height,
ppdev->ScreenHeight - 1);
SrcPoint.x = max(-ppdev->PointerAttributes.Column, 0);
SrcPoint.y = max(-ppdev->PointerAttributes.Row, 0);
DestSurf = EngLockSurface(ppdev->hSurfEng);
MaskSurf = EngLockSurface(ppdev->PointerMaskSurface);
if (ppdev->PointerColorSurface != NULL)
{
ColorSurf = EngLockSurface(ppdev->PointerColorSurface);
EngBitBlt(DestSurf, ColorSurf, MaskSurf, NULL, ppdev->XlateObject,
&DestRect, &SrcPoint, &SrcPoint, NULL, NULL, 0xAACC);
EngUnlockSurface(ColorSurf);
}
else
{
/* FIXME */
EngBitBlt(DestSurf, MaskSurf, NULL, NULL, NULL,
&DestRect, &SrcPoint, NULL, NULL, NULL, SRCAND);
SrcPoint.y += ppdev->PointerAttributes.Height;
EngBitBlt(DestSurf, MaskSurf, NULL, NULL, NULL,
&DestRect, &SrcPoint, NULL, NULL, NULL, SRCINVERT);
}
EngUnlockSurface(MaskSurf);
EngUnlockSurface(DestSurf);
}
}
/*
* DrvSetPointerShape
*
* Sets the new pointer shape.
*
* Status
* @implemented
*/
ULONG DDKAPI
DrvSetPointerShape(
IN SURFOBJ *pso,
IN SURFOBJ *psoMask,
IN SURFOBJ *psoColor,
IN XLATEOBJ *pxlo,
IN LONG xHot,
IN LONG yHot,
IN LONG x,
IN LONG y,
IN RECTL *prcl,
IN FLONG fl)
{
PPDEV ppdev = (PPDEV)pso->dhpdev;
SURFOBJ *TempSurfObj;
IntHideMousePointer(ppdev);
if (ppdev->PointerColorSurface != NULL)
{
/* FIXME: Is this really needed? */
TempSurfObj = EngLockSurface(ppdev->PointerColorSurface);
EngFreeMem(TempSurfObj->pvBits);
TempSurfObj->pvBits = 0;
EngUnlockSurface(TempSurfObj);
EngDeleteSurface(ppdev->PointerColorSurface);
ppdev->PointerMaskSurface = NULL;
}
if (ppdev->PointerMaskSurface != NULL)
{
/* FIXME: Is this really needed? */
TempSurfObj = EngLockSurface(ppdev->PointerMaskSurface);
EngFreeMem(TempSurfObj->pvBits);
TempSurfObj->pvBits = 0;
EngUnlockSurface(TempSurfObj);
EngDeleteSurface(ppdev->PointerMaskSurface);
ppdev->PointerMaskSurface = NULL;
}
if (ppdev->PointerSaveSurface != NULL)
{
EngDeleteSurface(ppdev->PointerSaveSurface);
ppdev->PointerSaveSurface = NULL;
}
/*
* See if we are being asked to hide the pointer.
*/
if (psoMask == NULL)
{
return SPS_ACCEPT_EXCLUDE;
}
ppdev->HotSpot.x = xHot;
ppdev->HotSpot.y = yHot;
ppdev->XlateObject = pxlo;
ppdev->PointerAttributes.Column = x - xHot;
ppdev->PointerAttributes.Row = y - yHot;
ppdev->PointerAttributes.Width = psoMask->lDelta << 3;
ppdev->PointerAttributes.Height = (psoMask->cjBits / psoMask->lDelta) >> 1;
if (psoColor != NULL)
{
SIZEL Size;
PBYTE Bits;
Size.cx = ppdev->PointerAttributes.Width;
Size.cy = ppdev->PointerAttributes.Height;
Bits = EngAllocMem(0, psoColor->cjBits, ALLOC_TAG);
memcpy(Bits, psoColor->pvBits, psoColor->cjBits);
ppdev->PointerColorSurface = (HSURF)EngCreateBitmap(Size,
psoColor->lDelta, psoColor->iBitmapFormat, 0, Bits);
}
else
{
ppdev->PointerColorSurface = NULL;
}
if (psoMask != NULL)
{
SIZEL Size;
PBYTE Bits;
Size.cx = ppdev->PointerAttributes.Width;
Size.cy = ppdev->PointerAttributes.Height << 1;
Bits = EngAllocMem(0, psoMask->cjBits, ALLOC_TAG);
memcpy(Bits, psoMask->pvBits, psoMask->cjBits);
ppdev->PointerMaskSurface = (HSURF)EngCreateBitmap(Size,
psoMask->lDelta, psoMask->iBitmapFormat, 0, Bits);
}
else
{
ppdev->PointerMaskSurface = NULL;
}
/*
* Create surface for saving the pixels under the cursor.
*/
{
SIZEL Size;
LONG lDelta;
Size.cx = ppdev->PointerAttributes.Width;
Size.cy = ppdev->PointerAttributes.Height;
switch (pso->iBitmapFormat)
{
case BMF_8BPP: lDelta = Size.cx; break;
case BMF_16BPP: lDelta = Size.cx << 1; break;
case BMF_24BPP: lDelta = Size.cx * 3; break;
case BMF_32BPP: lDelta = Size.cx << 2; break;
}
ppdev->PointerSaveSurface = (HSURF)EngCreateBitmap(
Size, lDelta, pso->iBitmapFormat, BMF_NOZEROINIT, NULL);
}
IntShowMousePointer(ppdev);
return SPS_ACCEPT_EXCLUDE;
}
/*
* DrvMovePointer
*
* Moves the pointer to a new position and ensures that GDI does not interfere
* with the display of the pointer.
*
* Status
* @implemented
*/
VOID DDKAPI
DrvMovePointer(
IN SURFOBJ *pso,
IN LONG x,
IN LONG y,
IN RECTL *prcl)
{
PPDEV ppdev = (PPDEV)pso->dhpdev;
BOOL WasVisible;
WasVisible = ppdev->PointerAttributes.Enable;
if (WasVisible)
{
IntHideMousePointer(ppdev);
}
if (x == -1)
{
return;
}
ppdev->PointerAttributes.Column = x - ppdev->HotSpot.x;
ppdev->PointerAttributes.Row = y - ppdev->HotSpot.y;
if (WasVisible)
{
IntShowMousePointer(ppdev);
}
}
#endif

View file

@ -111,6 +111,15 @@ DrvEnableSurface(
ppdev->hSurfEng = hSurface;
#ifdef EXPERIMENTAL_MOUSE_CURSOR_SUPPORT
ppdev->ScreenClipObj = EngCreateClip();
ppdev->ScreenClipObj->iDComplexity = DC_RECT;
ppdev->ScreenClipObj->rclBounds.left = 0;
ppdev->ScreenClipObj->rclBounds.top = 0;
ppdev->ScreenClipObj->rclBounds.right = ppdev->ScreenWidth;
ppdev->ScreenClipObj->rclBounds.bottom = ppdev->ScreenHeight;
#endif
return hSurface;
}
@ -130,9 +139,18 @@ DrvDisableSurface(
{
DWORD ulTemp;
VIDEO_MEMORY VideoMemory;
PPDEV ppdev = (PPDEV)dhpdev;
EngDeleteSurface(((PPDEV)dhpdev)->hSurfEng);
((PPDEV)dhpdev)->hSurfEng = NULL;
EngDeleteSurface(ppdev->hSurfEng);
ppdev->hSurfEng = NULL;
#ifdef EXPERIMENTAL_MOUSE_CURSOR_SUPPORT
EngDeleteClip(ppdev->ScreenClipObj);
ppdev->ScreenClipObj = NULL;
/* Clear all mouse pointer surfaces. */
DrvSetPointerShape(NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0);
#endif
/*
* Unmap the framebuffer.