mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 06:02:07 +00:00
Work on mouse pointer implementation.
svn path=/trunk/; revision=7864
This commit is contained in:
parent
ed4bb6a2cd
commit
db0f9b9ba4
4 changed files with 345 additions and 3 deletions
|
@ -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}
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue