* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: mouse.c,v 1.45 2003/11/16 12:36:24 gvg Exp $
+/* $Id$
*
* PROJECT: ReactOS kernel
* PURPOSE: Mouse
*/
/* INCLUDES ******************************************************************/
-#include <windows.h>
-#include <ddk/ntddk.h>
-#include <ddk/ntddmou.h>
-#include <win32k/win32k.h>
-#include <win32k/dc.h>
-#include "objects.h"
-#include "include/msgqueue.h"
-#include "include/object.h"
-#include "include/winsta.h"
-#include "include/cursoricon.h"
-#include "include/callback.h"
-#include <include/mouse.h>
+#include <w32k.h>
#define NDEBUG
#include <debug.h>
-#define GETSYSCURSOR(x) ((x) - OCR_NORMAL)
-
/* FUNCTIONS *****************************************************************/
-BOOL FASTCALL
-IntCheckClipCursor(LONG *x, LONG *y, PSYSTEM_CURSORINFO CurInfo)
-{
- if(CurInfo->CursorClipInfo.IsClipped)
- {
- if(*x > CurInfo->CursorClipInfo.Right)
- *x = CurInfo->CursorClipInfo.Right;
- if(*x < CurInfo->CursorClipInfo.Left)
- *x = CurInfo->CursorClipInfo.Left;
- if(*y > CurInfo->CursorClipInfo.Bottom)
- *y = CurInfo->CursorClipInfo.Bottom;
- if(*y < CurInfo->CursorClipInfo.Top)
- *y = CurInfo->CursorClipInfo.Top;
- return TRUE;
- }
- return TRUE;
-}
-
-BOOL FASTCALL
-IntDetectDblClick(PSYSTEM_CURSORINFO CurInfo, DWORD TickCount)
-{
- LONG dX, dY;
- BOOL res = ((TickCount - CurInfo->LastBtnDown) < CurInfo->DblClickSpeed);
- if(res)
- {
- /* check if the second click is within the DblClickWidth and DblClickHeight values */
- dX = CurInfo->LastBtnDownX - CurInfo->x;
- dY = CurInfo->LastBtnDownY - CurInfo->y;
- if(dX < 0) dX = -dX;
- if(dY < 0) dY = -dY;
-
- res = (dX <= CurInfo->DblClickWidth) &&
- (dY <= CurInfo->DblClickHeight);
-
- if(res)
- {
- CurInfo->LastBtnDown = 0; /* prevent sending 2 or more DBLCLK messages */
- CurInfo->LastBtnDownX = CurInfo->x;
- CurInfo->LastBtnDownY = CurInfo->y;
- }
- else
- {
- CurInfo->LastBtnDown = TickCount;
- CurInfo->LastBtnDownX = CurInfo->x;
- CurInfo->LastBtnDownY = CurInfo->y;
- }
- }
- else
- {
- CurInfo->LastBtnDown = TickCount;
- CurInfo->LastBtnDownX = CurInfo->x;
- CurInfo->LastBtnDownY = CurInfo->y;
- }
- return res;
-}
-
-BOOL FASTCALL
-IntSwapMouseButton(PWINSTATION_OBJECT WinStaObject, BOOL Swap)
-{
- BOOL res = WinStaObject->SystemCursor.SwapButtons;
- WinStaObject->SystemCursor.SwapButtons = Swap;
- return res;
-}
-
-INT STDCALL
-MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1,
+INT INTERNAL_CALL
+MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1,
LONG HazardY1, LONG HazardX2, LONG HazardY2)
/*
* FUNCTION: Notify the mouse driver that drawing is about to begin in
* a rectangle on a particular surface.
*/
{
- RECTL MouseRect;
LONG tmp;
- PSYSTEM_CURSORINFO CurInfo;
- BOOL MouseEnabled = FALSE;
- PCURICON_OBJECT Cursor;
-
+ GDIDEVICE *ppdev;
+ GDIPOINTER *pgp;
- /* Mouse is not allowed to move if GDI is busy drawing */
-
- if(IntGetWindowStationObject(InputWindowStation))
- {
- CurInfo = &InputWindowStation->SystemCursor;
-
- MouseEnabled = CurInfo->Enabled && CurInfo->ShowingCursor;
- }
- else
- return FALSE;
-
- ExAcquireFastMutexUnsafe(&CurInfo->CursorMutex);
- CurInfo->SafetySwitch2 = TRUE;
- ExReleaseFastMutexUnsafe(&CurInfo->CursorMutex);
-
- if (SurfObj == NULL)
- {
- ObDereferenceObject(InputWindowStation);
- return(FALSE);
- }
+ ASSERT(SurfObj != NULL);
+ ppdev = GDIDEV(SurfObj);
- if (SurfObj->iType != STYPE_DEVICE || MouseEnabled == FALSE)
+ if(ppdev == NULL)
{
- ObDereferenceObject(InputWindowStation);
return(FALSE);
}
- if (SPS_ACCEPT_NOEXCLUDE == SurfGDI->PointerStatus)
+ pgp = &ppdev->Pointer;
+
+ if (SPS_ACCEPT_NOEXCLUDE == pgp->Status ||
+ pgp->Exclude.right == -1)
{
- /* Hardware cursor, no need to remove it */
- ObDereferenceObject(InputWindowStation);
return(FALSE);
}
-
- if(!(Cursor = CurInfo->CurrentCursorObject))
- {
- ObDereferenceObject(InputWindowStation);
- return(FALSE);
- }
if (HazardX1 > HazardX2)
{
tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp;
}
- if (CurInfo->x - (INT) Cursor->IconInfo.xHotspot + Cursor->Size.cx >= HazardX1
- && CurInfo->x - (INT) Cursor->IconInfo.xHotspot <= HazardX2
- && CurInfo->y - (INT) Cursor->IconInfo.yHotspot + Cursor->Size.cy >= HazardY1
- && CurInfo->y - (INT) Cursor->IconInfo.yHotspot <= HazardY2)
+ if (ppdev->SafetyRemoveLevel != 0)
+ {
+ ppdev->SafetyRemoveCount++;
+ return FALSE;
+ }
+
+ ppdev->SafetyRemoveCount++;
+
+ if (pgp->Exclude.right >= HazardX1
+ && pgp->Exclude.left <= HazardX2
+ && pgp->Exclude.bottom >= HazardY1
+ && pgp->Exclude.top <= HazardY2)
{
- /* Mouse is not allowed to move if GDI is busy drawing */
- ExAcquireFastMutexUnsafe(&CurInfo->CursorMutex);
- CurInfo->SafetySwitch = TRUE;
- SurfGDI->MovePointer(SurfObj, -1, -1, &MouseRect);
- ExReleaseFastMutexUnsafe(&CurInfo->CursorMutex);
+ ppdev->SafetyRemoveLevel = ppdev->SafetyRemoveCount;
+ if (pgp->MovePointer)
+ pgp->MovePointer(SurfObj, -1, -1, NULL);
+ else
+ EngMovePointer(SurfObj, -1, -1, NULL);
}
-
- ObDereferenceObject(InputWindowStation);
+
return(TRUE);
}
-INT FASTCALL
-MouseSafetyOnDrawEnd(PSURFOBJ SurfObj, PSURFGDI SurfGDI)
+INT INTERNAL_CALL
+MouseSafetyOnDrawEnd(SURFOBJ *SurfObj)
/*
* FUNCTION: Notify the mouse driver that drawing has finished on a surface.
*/
{
- RECTL MouseRect;
- PSYSTEM_CURSORINFO CurInfo;
- BOOL MouseEnabled = FALSE;
-
- if(IntGetWindowStationObject(InputWindowStation))
- {
- CurInfo = &InputWindowStation->SystemCursor;
- }
- else
- return FALSE;
-
- if(SurfObj == NULL)
- {
- ExAcquireFastMutexUnsafe(&CurInfo->CursorMutex);
- CurInfo->SafetySwitch2 = FALSE;
- ExReleaseFastMutexUnsafe(&CurInfo->CursorMutex);
- ObDereferenceObject(InputWindowStation);
- return FALSE;
- }
-
- MouseEnabled = CurInfo->Enabled && CurInfo->ShowingCursor;
+ GDIDEVICE *ppdev;
+ GDIPOINTER *pgp;
- if (SurfObj->iType != STYPE_DEVICE || MouseEnabled == FALSE)
- {
- ExAcquireFastMutexUnsafe(&CurInfo->CursorMutex);
- CurInfo->SafetySwitch2 = FALSE;
- ExReleaseFastMutexUnsafe(&CurInfo->CursorMutex);
- ObDereferenceObject(InputWindowStation);
- return(FALSE);
- }
+ ASSERT(SurfObj != NULL);
+
+ ppdev = GDIDEV(SurfObj);
- if (SPS_ACCEPT_NOEXCLUDE == SurfGDI->PointerStatus)
+ if(ppdev == NULL)
{
- /* Hardware cursor, it wasn't removed so need to restore it */
- ExAcquireFastMutexUnsafe(&CurInfo->CursorMutex);
- CurInfo->SafetySwitch2 = FALSE;
- ExReleaseFastMutexUnsafe(&CurInfo->CursorMutex);
- ObDereferenceObject(InputWindowStation);
return(FALSE);
}
-
- ExAcquireFastMutexUnsafe(&CurInfo->CursorMutex);
- if (CurInfo->SafetySwitch)
- {
- SurfGDI->MovePointer(SurfObj, CurInfo->x, CurInfo->y, &MouseRect);
- CurInfo->SafetySwitch = FALSE;
- CurInfo->SafetySwitch2 = FALSE;
- }
- else
- {
- CurInfo->SafetySwitch2 = FALSE;
- }
- ExReleaseFastMutexUnsafe(&CurInfo->CursorMutex);
- ObDereferenceObject(InputWindowStation);
- return(TRUE);
-}
-BOOL FASTCALL
-MouseMoveCursor(LONG X, LONG Y)
-{
- HDC hDC;
- PDC dc;
- RECTL MouseRect;
- BOOL res = FALSE;
- PSURFOBJ SurfObj;
- PSURFGDI SurfGDI;
- PSYSTEM_CURSORINFO CurInfo;
- MSG Msg;
- LARGE_INTEGER LargeTickCount;
- ULONG TickCount;
-
- if(!InputWindowStation)
- return FALSE;
-
- if(IntGetWindowStationObject(InputWindowStation))
+ pgp = &ppdev->Pointer;
+
+ if(SPS_ACCEPT_NOEXCLUDE == pgp->Status ||
+ pgp->Exclude.right == -1)
{
- CurInfo = &InputWindowStation->SystemCursor;
- if(!CurInfo->Enabled)
- {
- ObDereferenceObject(InputWindowStation);
- return FALSE;
- }
- hDC = IntGetScreenDC();
- if(!hDC)
- {
- ObDereferenceObject(InputWindowStation);
- return FALSE;
- }
- dc = DC_LockDc(hDC);
- SurfObj = (PSURFOBJ)AccessUserObject((ULONG) dc->Surface);
- SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) dc->Surface);
- DC_UnlockDc( hDC );
- IntCheckClipCursor(&X, &Y, CurInfo);
- if((X != CurInfo->x) || (Y != CurInfo->y))
- {
- /* send MOUSEMOVE message */
- KeQueryTickCount(&LargeTickCount);
- TickCount = LargeTickCount.u.LowPart;
- Msg.wParam = CurInfo->ButtonsDown;
- Msg.lParam = MAKELPARAM(X, Y);
- Msg.message = WM_MOUSEMOVE;
- Msg.time = TickCount;
- Msg.pt.x = X;
- Msg.pt.y = Y;
- MsqInsertSystemMessage(&Msg, TRUE);
- /* move cursor */
- CurInfo->x = X;
- CurInfo->y = Y;
- if(CurInfo->Enabled)
- {
- ExAcquireFastMutexUnsafe(&CurInfo->CursorMutex);
- SurfGDI->MovePointer(SurfObj, CurInfo->x, CurInfo->y, &MouseRect);
- ExReleaseFastMutexUnsafe(&CurInfo->CursorMutex);
- }
- res = TRUE;
- }
-
- ObDereferenceObject(InputWindowStation);
- return res;
+ return FALSE;
}
+
+ if (--ppdev->SafetyRemoveCount >= ppdev->SafetyRemoveLevel)
+ {
+ return FALSE;
+ }
+ if (pgp->MovePointer)
+ pgp->MovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, &pgp->Exclude);
else
- return FALSE;
+ EngMovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, &pgp->Exclude);
+
+ ppdev->SafetyRemoveLevel = 0;
+
+ return(TRUE);
}
-VOID /* STDCALL */
-MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
-/*
- * FUNCTION: Call by the mouse driver when input events occur.
- */
+/* SOFTWARE MOUSE POINTER IMPLEMENTATION **************************************/
+
+VOID INTERNAL_CALL
+IntHideMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface)
{
- ULONG i;
- PSYSTEM_CURSORINFO CurInfo;
- BOOL MouseEnabled = FALSE;
- BOOL MouseMoveAdded = FALSE;
- BOOL Moved = FALSE;
- LONG mouse_ox, mouse_oy;
- LONG mouse_cx = 0, mouse_cy = 0;
- LONG dScroll = 0;
- HDC hDC;
- PDC dc;
- PSURFOBJ SurfObj;
- PSURFGDI SurfGDI;
- RECTL MouseRect;
- WORD wp;
- MSG Msg;
- LARGE_INTEGER LargeTickCount;
- ULONG TickCount;
-
- hDC = IntGetScreenDC();
-
- if(!hDC || !InputWindowStation)
- return;
-
- if(IntGetWindowStationObject(InputWindowStation))
- {
- CurInfo = &InputWindowStation->SystemCursor;
- MouseEnabled = CurInfo->Enabled;
- if(!MouseEnabled)
- {
- ObDereferenceObject(InputWindowStation);
+ GDIPOINTER *pgp;
+ POINTL pt;
+
+ ASSERT(ppdev);
+ ASSERT(DestSurface);
+
+ pgp = &ppdev->Pointer;
+
+ if (!pgp->Enabled)
+ {
return;
- }
- mouse_ox = CurInfo->x;
- mouse_oy = CurInfo->y;
- }
- else
- return;
+ }
- dc = DC_LockDc(hDC);
- SurfObj = (PSURFOBJ)AccessUserObject((ULONG) dc->Surface);
- SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) dc->Surface);
- DC_UnlockDc( hDC );
+
- /* Compile the total mouse movement change and dispatch button events. */
- for (i = 0; i < InputCount; i++)
- {
- mouse_cx += Data[i].LastX;
- mouse_cy += Data[i].LastY;
-
- CurInfo->x += Data[i].LastX;
- CurInfo->y += Data[i].LastY;
-
- CurInfo->x = max(CurInfo->x, 0);
- CurInfo->y = max(CurInfo->y, 0);
- CurInfo->x = min(CurInfo->x, SurfObj->sizlBitmap.cx - 1);
- CurInfo->y = min(CurInfo->y, SurfObj->sizlBitmap.cy - 1);
-
- IntCheckClipCursor(&CurInfo->x, &CurInfo->y, CurInfo);
-
- KeQueryTickCount(&LargeTickCount);
- TickCount = LargeTickCount.u.LowPart;
-
- Msg.wParam = CurInfo->ButtonsDown;
- Msg.lParam = MAKELPARAM(CurInfo->x, CurInfo->y);
- Msg.message = WM_MOUSEMOVE;
- Msg.time = TickCount;
- Msg.pt.x = CurInfo->x;
- Msg.pt.y = CurInfo->y;
-
- MouseMoveAdded = FALSE;
-
- //PrintInputData(i, Data[i]);
-
- if (Data[i].ButtonFlags != 0)
- {
- wp = 0;
- if ((Data[i].ButtonFlags & MOUSE_LEFT_BUTTON_DOWN) > 0)
- {
- /* insert WM_MOUSEMOVE messages before Button down messages */
- if ((0 != Data[i].LastX) || (0 != Data[i].LastY))
- {
- MsqInsertSystemMessage(&Msg, FALSE);
- MouseMoveAdded = TRUE;
- }
- CurInfo->ButtonsDown |= CurInfo->SwapButtons ? MK_RBUTTON : MK_LBUTTON;
- if(IntDetectDblClick(CurInfo, TickCount))
- Msg.message = CurInfo->SwapButtons ? WM_RBUTTONDBLCLK : WM_LBUTTONDBLCLK;
- else
- Msg.message = CurInfo->SwapButtons ? WM_RBUTTONDOWN : WM_LBUTTONDOWN;
- }
- if ((Data[i].ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN) > 0)
- {
- /* insert WM_MOUSEMOVE messages before Button down messages */
- if ((0 != Data[i].LastX) || (0 != Data[i].LastY))
- {
- MsqInsertSystemMessage(&Msg, FALSE);
- MouseMoveAdded = TRUE;
- }
- CurInfo->ButtonsDown |= MK_MBUTTON;
- if(IntDetectDblClick(CurInfo, TickCount))
- Msg.message = WM_MBUTTONDBLCLK;
- else
- Msg.message = WM_MBUTTONDOWN;
- }
- if ((Data[i].ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN) > 0)
+ pgp->Enabled = FALSE;
+
+ pt.x = pgp->Pos.x - pgp->HotSpot.x;
+ pt.y = pgp->Pos.y - pgp->HotSpot.y;
+
+
+ if (pgp->SaveSurface != NULL)
+ {
+ RECTL DestRect;
+ POINTL SrcPoint;
+ SURFOBJ *SaveSurface;
+ SURFOBJ *MaskSurface;
+
+ DestRect.left = max(pt.x, 0);
+ DestRect.top = max(pt.y, 0);
+ DestRect.right = min(
+ pt.x + pgp->Size.cx,
+ DestSurface->sizlBitmap.cx);
+ DestRect.bottom = min(
+ pt.y + pgp->Size.cy,
+ DestSurface->sizlBitmap.cy);
+
+ SrcPoint.x = max(-pt.x, 0);
+ SrcPoint.y = max(-pt.y, 0);
+
+ if((SaveSurface = EngLockSurface(pgp->SaveSurface)))
{
- /* insert WM_MOUSEMOVE messages before Button down messages */
- if ((0 != Data[i].LastX) || (0 != Data[i].LastY))
+ if((MaskSurface = EngLockSurface(pgp->MaskSurface)))
{
- MsqInsertSystemMessage(&Msg, FALSE);
- MouseMoveAdded = TRUE;
+ IntEngBitBltEx(DestSurface, SaveSurface, MaskSurface, NULL, NULL,
+ &DestRect, &SrcPoint, &SrcPoint, NULL, NULL,
+ ROP3_TO_ROP4(SRCCOPY), FALSE);
+ EngUnlockSurface(MaskSurface);
}
- CurInfo->ButtonsDown |= CurInfo->SwapButtons ? MK_LBUTTON : MK_RBUTTON;
- if(IntDetectDblClick(CurInfo, TickCount))
- Msg.message = CurInfo->SwapButtons ? WM_LBUTTONDBLCLK : WM_RBUTTONDBLCLK;
- else
- Msg.message = CurInfo->SwapButtons ? WM_LBUTTONDOWN : WM_RBUTTONDOWN;
+ EngUnlockSurface(SaveSurface);
}
-
- if ((Data[i].ButtonFlags & MOUSE_BUTTON_4_DOWN) > 0)
+ }
+}
+
+VOID INTERNAL_CALL
+IntShowMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface)
+{
+ GDIPOINTER *pgp;
+ SURFOBJ *SaveSurface;
+ POINTL pt;
+
+ ASSERT(ppdev);
+ ASSERT(DestSurface);
+
+ pgp = &ppdev->Pointer;
+
+ if (pgp->Enabled)
+ {
+ return;
+ }
+
+ if (pgp->ShowPointer == 1)
+ {
+ return ;
+ }
+
+
+ pgp->Enabled = TRUE;
+
+ pt.x = pgp->Pos.x - pgp->HotSpot.x;
+ pt.y = pgp->Pos.y - pgp->HotSpot.y;
+
+ /*
+ * Copy the pixels under the cursor to temporary surface.
+ */
+
+ if (pgp->SaveSurface != NULL &&
+ (SaveSurface = EngLockSurface(pgp->SaveSurface)))
+ {
+ RECTL DestRect;
+ POINTL SrcPoint;
+
+ SrcPoint.x = max(pt.x, 0);
+ SrcPoint.y = max(pt.y, 0);
+
+ DestRect.left = SrcPoint.x - pt.x;
+ DestRect.top = SrcPoint.y - pt.y;
+ DestRect.right = min(
+ pgp->Size.cx,
+ DestSurface->sizlBitmap.cx - pt.x);
+ DestRect.bottom = min(
+ pgp->Size.cy,
+ DestSurface->sizlBitmap.cy - pt.y);
+
+ IntEngBitBltEx(SaveSurface, DestSurface, NULL, NULL, NULL,
+ &DestRect, &SrcPoint, NULL, NULL, NULL,
+ ROP3_TO_ROP4(SRCCOPY), FALSE);
+ EngUnlockSurface(SaveSurface);
+ }
+
+ /*
+ * Blit the cursor on the screen.
+ */
+
+ {
+ RECTL DestRect;
+ POINTL SrcPoint;
+ SURFOBJ *ColorSurf;
+ SURFOBJ *MaskSurf = NULL;
+
+ DestRect.left = max(pt.x, 0);
+ DestRect.top = max(pt.y, 0);
+ DestRect.right = min(
+ pt.x + pgp->Size.cx,
+ DestSurface->sizlBitmap.cx);
+ DestRect.bottom = min(
+ pt.y + pgp->Size.cy,
+ DestSurface->sizlBitmap.cy);
+
+ SrcPoint.x = max(-pt.x, 0);
+ SrcPoint.y = max(-pt.y, 0);
+
+ if (pgp->MaskSurface)
+ MaskSurf = EngLockSurface(pgp->MaskSurface);
+
+ if (MaskSurf != NULL)
{
- /* insert WM_MOUSEMOVE messages before Button down messages */
- if ((0 != Data[i].LastX) || (0 != Data[i].LastY))
+ if (pgp->ColorSurface != NULL)
{
- MsqInsertSystemMessage(&Msg, FALSE);
- MouseMoveAdded = TRUE;
+ if((ColorSurf = EngLockSurface(pgp->ColorSurface)))
+ {
+ IntEngBitBltEx(DestSurface, ColorSurf, MaskSurf, NULL,
+ pgp->XlateObject, &DestRect, &SrcPoint, &SrcPoint,
+ NULL, NULL, R4_MASK, FALSE);
+ EngUnlockSurface(ColorSurf);
+ }
}
- CurInfo->ButtonsDown |= MK_XBUTTON1;
- if(IntDetectDblClick(CurInfo, TickCount))
- {
- Msg.message = WM_XBUTTONDBLCLK;
- wp = XBUTTON1;
- }
- else
- Msg.message = WM_XBUTTONDOWN;
- }
- if ((Data[i].ButtonFlags & MOUSE_BUTTON_5_DOWN) > 0)
- {
- /* insert WM_MOUSEMOVE messages before Button down messages */
- if ((0 != Data[i].LastX) || (0 != Data[i].LastY))
+ else
{
- MsqInsertSystemMessage(&Msg, FALSE);
- MouseMoveAdded = TRUE;
+ IntEngBitBltEx(DestSurface, MaskSurf, NULL, NULL, pgp->XlateObject,
+ &DestRect, &SrcPoint, NULL, NULL, NULL,
+ ROP3_TO_ROP4(SRCAND), FALSE);
+ SrcPoint.y += pgp->Size.cy;
+ IntEngBitBltEx(DestSurface, MaskSurf, NULL, NULL, pgp->XlateObject,
+ &DestRect, &SrcPoint, NULL, NULL, NULL,
+ ROP3_TO_ROP4(SRCINVERT), FALSE);
}
- CurInfo->ButtonsDown |= MK_XBUTTON2;
- if(IntDetectDblClick(CurInfo, TickCount))
- {
- Msg.message = WM_XBUTTONDBLCLK;
- wp = XBUTTON2;
- }
- else
- Msg.message = WM_XBUTTONDOWN;
+ EngUnlockSurface(MaskSurf);
}
+ }
+}
- if ((Data[i].ButtonFlags & MOUSE_LEFT_BUTTON_UP) > 0)
- {
- CurInfo->ButtonsDown &= CurInfo->SwapButtons ? ~MK_RBUTTON : ~MK_LBUTTON;
- Msg.message = CurInfo->SwapButtons ? WM_RBUTTONUP : WM_LBUTTONUP;
- }
- if ((Data[i].ButtonFlags & MOUSE_MIDDLE_BUTTON_UP) > 0)
- {
- CurInfo->ButtonsDown &= ~MK_MBUTTON;
- Msg.message = WM_MBUTTONUP;
- }
- if ((Data[i].ButtonFlags & MOUSE_RIGHT_BUTTON_UP) > 0)
+/*
+ * @implemented
+ */
+
+ULONG STDCALL
+EngSetPointerShape(
+ 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)
+{
+ GDIDEVICE *ppdev;
+ SURFOBJ *TempSurfObj;
+ GDIPOINTER *pgp;
+
+ ASSERT(pso);
+
+ ppdev = GDIDEV(pso);
+ pgp = &ppdev->Pointer;
+
+ IntHideMousePointer(ppdev, pso);
+
+ if (pgp->ColorSurface != NULL)
+ {
+ /* FIXME: Is this really needed? */
+ if((TempSurfObj = EngLockSurface(pgp->ColorSurface)))
{
- CurInfo->ButtonsDown &= CurInfo->SwapButtons ? ~MK_LBUTTON : ~MK_RBUTTON;
- Msg.message = CurInfo->SwapButtons ? WM_LBUTTONUP : WM_RBUTTONUP;
+ EngFreeMem(TempSurfObj->pvBits);
+ TempSurfObj->pvBits = 0;
+ EngUnlockSurface(TempSurfObj);
}
- if ((Data[i].ButtonFlags & MOUSE_BUTTON_4_UP) > 0)
+
+ EngDeleteSurface(pgp->ColorSurface);
+ pgp->MaskSurface = NULL;
+ }
+
+ if (pgp->MaskSurface != NULL)
+ {
+ /* FIXME: Is this really needed? */
+ if((TempSurfObj = EngLockSurface(pgp->MaskSurface)))
{
- CurInfo->ButtonsDown &= ~MK_XBUTTON1;
- Msg.message = WM_XBUTTONUP;
+ EngFreeMem(TempSurfObj->pvBits);
+ TempSurfObj->pvBits = 0;
+ EngUnlockSurface(TempSurfObj);
}
- if ((Data[i].ButtonFlags & MOUSE_BUTTON_5_UP) > 0)
+
+ EngDeleteSurface(pgp->MaskSurface);
+ pgp->MaskSurface = NULL;
+ }
+
+ if (pgp->SaveSurface != NULL)
+ {
+ EngDeleteSurface(pgp->SaveSurface);
+ pgp->SaveSurface = NULL;
+ }
+
+ if (pgp->XlateObject != NULL)
+ {
+ EngDeleteXlate(pgp->XlateObject);
+ pgp->XlateObject = NULL;
+ }
+
+ /*
+ * See if we are being asked to hide the pointer.
+ */
+
+ if (psoMask == NULL)
+ {
+ return SPS_ACCEPT_NOEXCLUDE;
+ }
+
+ pgp->HotSpot.x = xHot;
+ pgp->HotSpot.y = yHot;
+
+ /* Actually this should be set by 'the other side', but it would be
+ * done right after this. It helps IntShowMousePointer. */
+ if (x != -1)
+ {
+ pgp->Pos.x = x;
+ pgp->Pos.y = y;
+ }
+
+ pgp->Size.cx = abs(psoMask->lDelta) << 3;
+ pgp->Size.cy = (psoMask->cjBits / abs(psoMask->lDelta)) >> 1;
+
+ if (psoColor != NULL)
+ {
+ PBYTE Bits;
+
+ Bits = EngAllocMem(0, psoColor->cjBits, TAG_MOUSE);
+ if (Bits == NULL)
{
- CurInfo->ButtonsDown &= ~MK_XBUTTON2;
- Msg.message = WM_XBUTTONUP;
+ return SPS_ERROR;
}
- if ((Data[i].ButtonFlags & MOUSE_WHEEL) > 0)
+
+ memcpy(Bits, psoColor->pvBits, psoColor->cjBits);
+
+ pgp->ColorSurface = (HSURF)EngCreateBitmap(pgp->Size,
+ psoColor->lDelta, psoColor->iBitmapFormat,
+ psoColor->lDelta < 0 ? 0 : BMF_TOPDOWN, Bits);
+ }
+ else
+ {
+ pgp->ColorSurface = NULL;
+ }
+
+ {
+ SIZEL Size;
+ PBYTE Bits;
+
+ Size.cx = pgp->Size.cx;
+ Size.cy = pgp->Size.cy << 1;
+ Bits = EngAllocMem(0, psoMask->cjBits, TAG_MOUSE);
+ if (Bits == NULL)
{
- dScroll += (LONG)Data[i].ButtonData;
+ return SPS_ERROR;
}
- if (Data[i].ButtonFlags != MOUSE_WHEEL)
+ memcpy(Bits, psoMask->pvBits, psoMask->cjBits);
+
+ pgp->MaskSurface = (HSURF)EngCreateBitmap(Size,
+ psoMask->lDelta, psoMask->iBitmapFormat,
+ psoMask->lDelta < 0 ? 0 : BMF_TOPDOWN, Bits);
+ }
+
+ /*
+ * Create an XLATEOBJ that will be used for drawing masks.
+ * FIXME: We should get this in pxlo parameter!
+ */
+
+ if (pxlo == NULL)
+ {
+ HPALETTE BWPalette, DestPalette;
+ ULONG BWColors[] = {0, 0xFFFFFF};
+
+ BWPalette = EngCreatePalette(PAL_INDEXED, sizeof(BWColors) / sizeof(ULONG),
+ BWColors, 0, 0, 0);
+
+ DestPalette = ppdev->DevInfo.hpalDefault;
+ pgp->XlateObject = IntEngCreateXlate(0, PAL_INDEXED,
+ DestPalette, BWPalette);
+ EngDeletePalette(BWPalette);
+ }
+ else
+ {
+ pgp->XlateObject = pxlo;
+ }
+
+ /*
+ * Create surface for saving the pixels under the cursor.
+ */
+
+ {
+ LONG lDelta;
+
+ switch (pso->iBitmapFormat)
{
- Moved = (0 != mouse_cx) || (0 != mouse_cy);
- if(Moved && MouseEnabled)
- {
- if (!CurInfo->SafetySwitch && !CurInfo->SafetySwitch2 &&
- ((mouse_ox != CurInfo->x) || (mouse_oy != CurInfo->y)))
- {
- ExAcquireFastMutexUnsafe(&CurInfo->CursorMutex);
- SurfGDI->MovePointer(SurfObj, CurInfo->x, CurInfo->y, &MouseRect);
- ExReleaseFastMutexUnsafe(&CurInfo->CursorMutex);
- mouse_cx = 0;
- mouse_cy = 0;
- }
- }
-
- Msg.wParam = CurInfo->ButtonsDown;
- MsqInsertSystemMessage(&Msg, FALSE);
-
- /* insert WM_MOUSEMOVE messages after Button up messages */
- if(!MouseMoveAdded && Moved)
- {
- Msg.message = WM_MOUSEMOVE;
- MsqInsertSystemMessage(&Msg, FALSE);
- MouseMoveAdded = TRUE;
- }
+ case BMF_1BPP:
+ lDelta = pgp->Size.cx >> 3;
+ break;
+ case BMF_4BPP:
+ lDelta = pgp->Size.cx >> 1;
+ break;
+ case BMF_8BPP:
+ lDelta = pgp->Size.cx;
+ break;
+ case BMF_16BPP:
+ lDelta = pgp->Size.cx << 1;
+ break;
+ case BMF_24BPP:
+ lDelta = pgp->Size.cx * 3;
+ break;
+ case BMF_32BPP:
+ lDelta = pgp->Size.cx << 2;
+ break;
+ default:
+ lDelta = 0;
+ break;
}
- }
- }
-
- KeQueryTickCount(&LargeTickCount);
- TickCount = LargeTickCount.u.LowPart;
- /* If the mouse moved then move the pointer. */
- if ((mouse_cx != 0 || mouse_cy != 0) && MouseEnabled)
- {
+ pgp->SaveSurface = (HSURF)EngCreateBitmap(
+ pgp->Size, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
+ }
+
+ if(x != -1)
+ {
+ IntShowMousePointer(ppdev, pso);
+
+ if (prcl != NULL)
+ {
+ prcl->left = x - pgp->HotSpot.x;
+ prcl->top = y - pgp->HotSpot.x;
+ prcl->right = prcl->left + pgp->Size.cx;
+ prcl->bottom = prcl->top + pgp->Size.cy;
+ }
+ } else if (prcl != NULL)
+ prcl->left = prcl->top = prcl->right = prcl->bottom = -1;
+
+ return SPS_ACCEPT_EXCLUDE;
+}
- if(!MouseMoveAdded)
- {
- Msg.wParam = CurInfo->ButtonsDown;
- Msg.message = WM_MOUSEMOVE;
- Msg.pt.x = CurInfo->x;
- Msg.pt.y = CurInfo->y;
- Msg.time = TickCount;
- Msg.lParam = MAKELPARAM(CurInfo->x, CurInfo->y);
- MsqInsertSystemMessage(&Msg, TRUE);
- }
-
- if (!CurInfo->SafetySwitch && !CurInfo->SafetySwitch2 &&
- ((mouse_ox != CurInfo->x) || (mouse_oy != CurInfo->y)))
- {
- ExAcquireFastMutexUnsafe(&CurInfo->CursorMutex);
- SurfGDI->MovePointer(SurfObj, CurInfo->x, CurInfo->y, &MouseRect);
- ExReleaseFastMutexUnsafe(&CurInfo->CursorMutex);
- }
- }
-
- /* send WM_MOUSEWHEEL message */
- if(dScroll && MouseEnabled)
- {
- Msg.message = WM_MOUSEWHEEL;
- Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, dScroll);
- Msg.lParam = MAKELPARAM(CurInfo->x, CurInfo->y);
- Msg.time = TickCount;
- Msg.pt.x = CurInfo->x;
- Msg.pt.y = CurInfo->y;
- MsqInsertSystemMessage(&Msg, FALSE);
- }
+/*
+ * @implemented
+ */
+
+VOID STDCALL
+EngMovePointer(
+ IN SURFOBJ *pso,
+ IN LONG x,
+ IN LONG y,
+ IN RECTL *prcl)
+{
+ GDIDEVICE *ppdev;
+ GDIPOINTER *pgp;
+
+ ASSERT(pso);
+
+ ppdev = GDIDEV(pso);
+
+ ASSERT(ppdev);
+
+ pgp = &ppdev->Pointer;
+
+ IntHideMousePointer(ppdev, pso);
+ if (x != -1)
+ {
+ /* Actually this should be set by 'the other side', but it would be
+ * done right after this. It helps IntShowMousePointer. */
+ pgp->Pos.x = x;
+ pgp->Pos.y = y;
+ IntShowMousePointer(ppdev, pso);
+ if (prcl != NULL)
+ {
+ prcl->left = x - pgp->HotSpot.x;
+ prcl->top = y - pgp->HotSpot.x;
+ prcl->right = prcl->left + pgp->Size.cx;
+ prcl->bottom = prcl->top + pgp->Size.cy;
+ }
+ } else if (prcl != NULL)
+ prcl->left = prcl->top = prcl->right = prcl->bottom = -1;
- ObDereferenceObject(InputWindowStation);
}
-VOID FASTCALL
-EnableMouse(HDC hDisplayDC)
+VOID STDCALL
+IntEngMovePointer(
+ IN SURFOBJ *SurfObj,
+ IN LONG x,
+ IN LONG y,
+ IN RECTL *prcl)
{
- PDC dc;
- PSURFOBJ SurfObj;
- PSURFGDI SurfGDI;
+ BITMAPOBJ *BitmapObj = CONTAINING_RECORD(SurfObj, BITMAPOBJ, SurfObj);
- if( hDisplayDC && InputWindowStation)
- {
- if(!IntGetWindowStationObject(InputWindowStation))
+ BITMAPOBJ_LockBitmapBits(BitmapObj);
+ if (GDIDEV(SurfObj)->Pointer.MovePointer)
{
- InputWindowStation->SystemCursor.Enabled = FALSE;
- return;
+ GDIDEV(SurfObj)->Pointer.MovePointer(SurfObj, x, y, prcl);
}
- IntSetCursor(InputWindowStation, NULL, TRUE);
-
- dc = DC_LockDc(hDisplayDC);
- SurfObj = (PSURFOBJ)AccessUserObject((ULONG) dc->Surface);
- SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) dc->Surface);
- DC_UnlockDc( hDisplayDC );
-
- InputWindowStation->SystemCursor.Enabled = (SPS_ACCEPT_EXCLUDE == SurfGDI->PointerStatus ||
- SPS_ACCEPT_NOEXCLUDE == SurfGDI->PointerStatus);
-
- /* Move the cursor to the screen center */
- DPRINT("Setting Cursor up at 0x%x, 0x%x\n", SurfObj->sizlBitmap.cx / 2, SurfObj->sizlBitmap.cy / 2);
- MouseMoveCursor(SurfObj->sizlBitmap.cx / 2, SurfObj->sizlBitmap.cy / 2);
-
- ObDereferenceObject(InputWindowStation);
- }
else
- {
- if(IntGetWindowStationObject(InputWindowStation))
{
- IntSetCursor(InputWindowStation, NULL, TRUE);
- InputWindowStation->SystemCursor.Enabled = FALSE;
- InputWindowStation->SystemCursor.CursorClipInfo.IsClipped = FALSE;
- ObDereferenceObject(InputWindowStation);
- return;
+ EngMovePointer(SurfObj, x, y, prcl);
}
- }
+ BITMAPOBJ_UnlockBitmapBits(BitmapObj);
}
+
/* EOF */