/* * ReactOS Generic Framebuffer display driver * * Copyright (C) 2004 Filip Navara * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "framebuf.h" #ifndef EXPERIMENTAL_MOUSE_CURSOR_SUPPORT /* * DrvSetPointerShape * * Sets the new pointer shape. * * Status * @unimplemented */ ULONG APIENTRY 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) { /* return SPS_DECLINE;*/ return EngSetPointerShape(pso, psoMask, psoColor, pxlo, xHot, yHot, x, y, prcl, fl); } /* * DrvMovePointer * * Moves the pointer to a new position and ensures that GDI does not interfere * with the display of the pointer. * * Status * @unimplemented */ VOID APIENTRY DrvMovePointer( IN SURFOBJ *pso, IN LONG x, IN LONG y, IN RECTL *prcl) { EngMovePointer(pso, x, y, prcl); } #else VOID FASTCALL IntHideMousePointer(PPDEV ppdev, SURFOBJ *DestSurface) { if (ppdev->PointerAttributes.Enable == FALSE) { return; } ppdev->PointerAttributes.Enable = FALSE; if (ppdev->PointerSaveSurface != NULL) { RECTL DestRect; POINTL SrcPoint; SURFOBJ *SaveSurface; 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); MaskSurface = EngLockSurface(ppdev->PointerMaskSurface); EngBitBlt(DestSurface, SaveSurface, MaskSurface, NULL, NULL, &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, SRCCOPY); EngUnlockSurface(MaskSurface); EngUnlockSurface(SaveSurface); } } VOID FASTCALL IntShowMousePointer(PPDEV ppdev, SURFOBJ *DestSurface) { if (ppdev->PointerAttributes.Enable) { return; } ppdev->PointerAttributes.Enable = TRUE; /* * Copy the pixels under the cursor to temporary surface. */ if (ppdev->PointerSaveSurface != NULL) { RECTL DestRect; POINTL SrcPoint; SURFOBJ *SaveSurface; 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); EngBitBlt(SaveSurface, DestSurface, NULL, NULL, NULL, &DestRect, &SrcPoint, NULL, NULL, NULL, SRCCOPY); EngUnlockSurface(SaveSurface); } /* * Blit the cursor on the screen. */ { RECTL DestRect; POINTL SrcPoint; 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); MaskSurf = EngLockSurface(ppdev->PointerMaskSurface); if (ppdev->PointerColorSurface != NULL) { ColorSurf = EngLockSurface(ppdev->PointerColorSurface); EngBitBlt(DestSurface, ColorSurf, MaskSurf, NULL, ppdev->PointerXlateObject, &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, 0xAACC); EngUnlockSurface(ColorSurf); } else { /* FIXME */ EngBitBlt(DestSurface, MaskSurf, NULL, NULL, ppdev->PointerXlateObject, &DestRect, &SrcPoint, NULL, NULL, NULL, SRCAND); SrcPoint.y += ppdev->PointerAttributes.Height; EngBitBlt(DestSurface, MaskSurf, NULL, NULL, ppdev->PointerXlateObject, &DestRect, &SrcPoint, NULL, NULL, NULL, SRCINVERT); } EngUnlockSurface(MaskSurf); } } /* * DrvSetPointerShape * * Sets the new pointer shape. * * Status * @implemented */ ULONG APIENTRY 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, pso); if (ppdev->PointerColorSurface != NULL) { /* FIXME: Is this really needed? */ TempSurfObj = EngLockSurface(ppdev->PointerColorSurface); EngFreeMem(TempSurfObj->pvBits); TempSurfObj->pvBits = NULL; EngUnlockSurface(TempSurfObj); EngDeleteSurface(ppdev->PointerColorSurface); ppdev->PointerColorSurface = NULL; } if (ppdev->PointerMaskSurface != NULL) { /* FIXME: Is this really needed? */ TempSurfObj = EngLockSurface(ppdev->PointerMaskSurface); EngFreeMem(TempSurfObj->pvBits); TempSurfObj->pvBits = NULL; 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->PointerHotSpot.x = xHot; ppdev->PointerHotSpot.y = yHot; ppdev->PointerXlateObject = 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); } { 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); } /* * 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, pso); 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 APIENTRY 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, pso); } if (x == -1) { return; } ppdev->PointerAttributes.Column = x - ppdev->PointerHotSpot.x; ppdev->PointerAttributes.Row = y - ppdev->PointerHotSpot.y; if (WasVisible) { IntShowMousePointer(ppdev, pso); } } #endif