--- /dev/null
+/*
+ * 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 = 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->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);
+ }
+ 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, 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