From 0ced40be8e2e94bfe6043c6feb4565a9d7d64757 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Sun, 12 Dec 2004 17:56:52 +0000 Subject: [PATCH] fixed problems with mouse cursor handling svn path=/trunk/; revision=12051 --- .../drivers/video/displays/vga/main/enable.c | 12 +- .../video/displays/vga/objects/pointer.c | 114 +++++++++--------- reactos/drivers/video/displays/vga/vgaddi.h | 40 ++---- reactos/include/win32k/dc.h | 12 +- reactos/subsys/win32k/eng/mouse.c | 81 +++++++------ reactos/subsys/win32k/ntuser/cursoricon.c | 5 +- reactos/subsys/win32k/ntuser/input.c | 9 +- reactos/subsys/win32k/objects/dc.c | 7 +- 8 files changed, 131 insertions(+), 149 deletions(-) diff --git a/reactos/drivers/video/displays/vga/main/enable.c b/reactos/drivers/video/displays/vga/main/enable.c index 2a7fbaa03aa..efbfc16291c 100644 --- a/reactos/drivers/video/displays/vga/main/enable.c +++ b/reactos/drivers/video/displays/vga/main/enable.c @@ -1,9 +1,9 @@ /* * entry.c * - * $Revision: 1.4 $ - * $Author: chorns $ - * $Date: 2004/11/27 00:46:24 $ + * $Revision: 1.5 $ + * $Author: weiden $ + * $Date: 2004/12/12 17:56:51 $ * */ @@ -258,12 +258,6 @@ DrvEnablePDEV(IN DEVMODEW *DM, } PDev->KMDriver = Driver; DPRINT( "PDev: %x, Driver: %x\n", PDev, PDev->KMDriver ); - PDev->xyCursor.x = 320; - PDev->xyCursor.y = 240; - PDev->ptlExtent.x = 0; - PDev->ptlExtent.y = 0; - PDev->cExtent = 0; - PDev->flCursor = CURSOR_DOWN; gaulCap.ulHorzRes = 640; gaulCap.ulVertRes = 480; diff --git a/reactos/drivers/video/displays/vga/objects/pointer.c b/reactos/drivers/video/displays/vga/objects/pointer.c index 53ea3acacfa..8bdf5c27b20 100644 --- a/reactos/drivers/video/displays/vga/objects/pointer.c +++ b/reactos/drivers/video/displays/vga/objects/pointer.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: pointer.c,v 1.3 2004/07/03 13:45:42 navaraf Exp $ +/* $Id: pointer.c,v 1.4 2004/12/12 17:56:52 weiden Exp $ * * PROJECT: ReactOS VGA16 display driver * FILE: drivers/dd/vga/display/objects/pointer.c @@ -33,8 +33,6 @@ /* GLOBALS *******************************************************************/ -static LONG oldx, oldy; -static PSAVED_SCREEN_BITS ImageBehindCursor = NULL; static VOID VGADDI_HideCursor(PPDEV ppdev); static VOID VGADDI_ShowCursor(PPDEV ppdev, PRECTL prcl); @@ -166,6 +164,9 @@ BOOL InitPointer(PPDEV ppdev) ULONG CursorWidth = 32, CursorHeight = 32; ULONG PointerAttributesSize; ULONG SavedMemSize; + + ppdev->xyHotSpot.x = 0; + ppdev->xyHotSpot.y = 0; /* Determine the size of the pointer attributes */ PointerAttributesSize = sizeof(VIDEO_POINTER_ATTRIBUTES) + @@ -184,7 +185,7 @@ BOOL InitPointer(PPDEV ppdev) /* Allocate memory for the pixels behind the cursor */ SavedMemSize = ((((CursorWidth + 7) & ~0x7) + 16) * CursorHeight) >> 3; - ImageBehindCursor = VGADDI_AllocSavedScreenBits(SavedMemSize); + ppdev->ImageBehindCursor = VGADDI_AllocSavedScreenBits(SavedMemSize); return(TRUE); } @@ -197,20 +198,15 @@ DrvMovePointer(IN SURFOBJ* pso, { PPDEV ppdev = (PPDEV)pso->dhpdev; - if (x < 0 && 0 == (ppdev->flCursor & CURSOR_DOWN)) - { - /* x < 0 and y < 0 indicates we must hide the cursor */ - VGADDI_HideCursor(ppdev); - return; - } + VGADDI_HideCursor(ppdev); - ppdev->xyCursor.x = x; - ppdev->xyCursor.y = y; + if(x != -1) + { + ppdev->pPointerAttributes->Column = x; + ppdev->pPointerAttributes->Row = y; - if (0 == (ppdev->flCursor & CURSOR_DOWN)) - { - VGADDI_ShowCursor(ppdev, prcl); - } + VGADDI_ShowCursor(ppdev, prcl); + } } @@ -230,20 +226,14 @@ DrvSetPointerShape(SURFOBJ* pso, ULONG NewWidth, NewHeight; PUCHAR Src, Dest; ULONG i; - - /* Hide the cursor */ - if (ppdev->pPointerAttributes->Enable != 0 - && 0 == (ppdev->flCursor & CURSOR_DOWN)) - { - VGADDI_HideCursor(ppdev); - } - + if (! psoMask) { - ppdev->flCursor = CURSOR_DOWN; - return SPS_ACCEPT_EXCLUDE; + return SPS_DECLINE; } - ppdev->flCursor = ppdev->flCursor & (~ CURSOR_DOWN); + + /* Hide the cursor */ + VGADDI_HideCursor(ppdev); NewWidth = abs(psoMask->lDelta) << 3; NewHeight = (psoMask->cjBits / abs(psoMask->lDelta)) / 2; @@ -270,9 +260,9 @@ DrvSetPointerShape(SURFOBJ* pso, ppdev->pPointerAttributes = NewPointerAttributes; /* Reallocate the space for the saved bits. */ - VGADDI_FreeSavedScreenBits(ImageBehindCursor); + VGADDI_FreeSavedScreenBits(ppdev->ImageBehindCursor); SavedMemSize = ((((NewWidth + 7) & ~0x7) + 16) * NewHeight) >> 3; - ImageBehindCursor = VGADDI_AllocSavedScreenBits(SavedMemSize); + ppdev->ImageBehindCursor = VGADDI_AllocSavedScreenBits(SavedMemSize); } Src = (PUCHAR)psoMask->pvScan0; @@ -293,13 +283,17 @@ DrvSetPointerShape(SURFOBJ* pso, } /* Set the new cursor position */ - ppdev->xyCursor.x = x; - ppdev->xyCursor.y = y; ppdev->xyHotSpot.x = xHot; ppdev->xyHotSpot.y = yHot; - /* Show the cursor */ - VGADDI_ShowCursor(ppdev, prcl); + if(x != -1) + { + ppdev->pPointerAttributes->Column = x; + ppdev->pPointerAttributes->Row = y; + + /* show the cursor */ + VGADDI_ShowCursor(ppdev, prcl); + } return SPS_ACCEPT_EXCLUDE; } @@ -322,18 +316,25 @@ VGADDI_ComputePointerRect(PPDEV ppdev, LONG X, LONG Y, PRECTL Rect) static VOID VGADDI_HideCursor(PPDEV ppdev) { - RECTL Rect; + if(ppdev->pPointerAttributes->Enable) + { + LONG cx, cy; + RECTL Rect; + + ppdev->pPointerAttributes->Enable = 0; + + cx = ppdev->pPointerAttributes->Column - ppdev->xyHotSpot.x; + cy = ppdev->pPointerAttributes->Row - ppdev->xyHotSpot.y; + + VGADDI_ComputePointerRect(ppdev, cx, cy, &Rect); - VGADDI_ComputePointerRect(ppdev, oldx, oldy, &Rect); - - /* Display what was behind cursor */ - VGADDI_BltFromSavedScreenBits(Rect.left, - Rect.top, - ImageBehindCursor, - Rect.right - Rect.left, - Rect.bottom - Rect.top); - - ppdev->pPointerAttributes->Enable = 0; + /* Display what was behind cursor */ + VGADDI_BltFromSavedScreenBits(Rect.left, + Rect.top, + ppdev->ImageBehindCursor, + Rect.right - Rect.left, + Rect.bottom - Rect.top); + } } static VOID @@ -343,19 +344,21 @@ VGADDI_ShowCursor(PPDEV ppdev, PRECTL prcl) PUCHAR AndMask, XorMask; ULONG SizeX, SizeY; RECTL Rect; + + if(ppdev->pPointerAttributes->Enable) + { + return; + } + /* Mark the cursor as currently displayed. */ + ppdev->pPointerAttributes->Enable = 1; - if (ppdev->pPointerAttributes->Enable != 0) - { - VGADDI_HideCursor(ppdev); - } - - cx = ppdev->xyCursor.x - ppdev->xyHotSpot.x; - cy = ppdev->xyCursor.y - ppdev->xyHotSpot.y; + cx = ppdev->pPointerAttributes->Column - ppdev->xyHotSpot.x; + cy = ppdev->pPointerAttributes->Row - ppdev->xyHotSpot.y; /* Capture pixels behind the cursor */ VGADDI_ComputePointerRect(ppdev, cx, cy, &Rect); - VGADDI_BltToSavedScreenBits(ImageBehindCursor, + VGADDI_BltToSavedScreenBits(ppdev->ImageBehindCursor, Rect.left, Rect.top, Rect.right - Rect.left, @@ -384,13 +387,6 @@ VGADDI_ShowCursor(PPDEV ppdev, PRECTL prcl) ppdev->pPointerAttributes->WidthInBytes, VGA_XOR); - /* Save the new cursor location. */ - oldx = cx; - oldy = cy; - - /* Mark the cursor as currently displayed. */ - ppdev->pPointerAttributes->Enable = 1; - if (NULL != prcl) { *prcl = Rect; diff --git a/reactos/drivers/video/displays/vga/vgaddi.h b/reactos/drivers/video/displays/vga/vgaddi.h index 71088babe21..d811e3e8e2c 100644 --- a/reactos/drivers/video/displays/vga/vgaddi.h +++ b/reactos/drivers/video/displays/vga/vgaddi.h @@ -25,8 +25,15 @@ typedef struct _XYPAIR USHORT y; } XYPAIR; +typedef struct _SAVED_SCREEN_BITS +{ + BOOL Free; + DWORD Offset; + ULONG Size; + LIST_ENTRY ListEntry; +} SAVED_SCREEN_BITS, *PSAVED_SCREEN_BITS; + // Cursor states -#define CURSOR_DOWN 0x00000001 #define CURSOR_COLOR 0x00000004 #define CURSOR_HW 0x00000010 #define CURSOR_HW_ACTIVE 0x00000020 @@ -43,14 +50,11 @@ typedef struct _PDEV PVOID AssociatedSurf; // associated surface // Cursor - XYPAIR xyCursor; // cursor position XYPAIR xyHotSpot; // cursor hotspot - POINTL ptlExtent; // cursor extent - ULONG cExtent; // effective cursor extent - ULONG flCursor; // cursor status // Pointer PVIDEO_POINTER_ATTRIBUTES pPointerAttributes; // HW Pointer Attributes + PSAVED_SCREEN_BITS ImageBehindCursor; ULONG XorMaskStartOffset; // Start offset of hardware pointer // XOR mask relative to AND mask for // passing to HW pointer @@ -92,32 +96,6 @@ typedef enum { //typedef VOID (*PFN_BankControl)(PDEVSURF, ULONG, BANK_JUST); typedef VOID (*PFN_BankControl)(PVOID, ULONG, BANK_JUST); -#if 0 -// descriptor for a saved screen bits block - -typedef struct _SAVED_SCREEN_BITS -{ - BOOL bFlags; - PBYTE pjBuffer; // pointer to save buffer start - ULONG ulSize; // size of save buffer (per plane; display memory only) - ULONG ulSaveWidthInBytes; // # of bytes across save area (including - // partial edge bytes, if any) - ULONG ulDelta; // # of bytes from end of one saved scan's saved bits to - // start of next (system memory only) - PVOID pvNextSSB; // pointer to next saved screen bits block - // for system memory blocks, saved bits start immediately - // after this structure -} SAVED_SCREEN_BITS, *PSAVED_SCREEN_BITS; -#else -typedef struct _SAVED_SCREEN_BITS -{ - BOOL Free; - DWORD Offset; - ULONG Size; - LIST_ENTRY ListEntry; -} SAVED_SCREEN_BITS, *PSAVED_SCREEN_BITS; -#endif - // DEVSURF -- definition of a surface as seen and used by the various VGA // drivers diff --git a/reactos/include/win32k/dc.h b/reactos/include/win32k/dc.h index 0d5aedd7096..589aec4d14a 100644 --- a/reactos/include/win32k/dc.h +++ b/reactos/include/win32k/dc.h @@ -108,22 +108,22 @@ typedef struct _DC WIN_DC_INFO w; } DC, *PDC; -typedef struct _GDIPOINTER +typedef struct _GDIPOINTER /* should stay private to ENG */ { + /* private GDI pointer handling information, required for software emulation */ BOOL Enabled; POINTL Pos; SIZEL Size; POINTL HotSpot; - - PGD_MOVEPOINTER MovePointer; - XLATEOBJ *XlateObject; HSURF ColorSurface; HSURF MaskSurface; HSURF SaveSurface; - + + /* public pointer information */ + RECTL Exclude; /* required publicly for SPS_ACCEPT_EXCLUDE */ + PGD_MOVEPOINTER MovePointer; ULONG Status; - BOOL SafetySwitch; UINT SafetyRemoveCount; } GDIPOINTER, *PGDIPOINTER; diff --git a/reactos/subsys/win32k/eng/mouse.c b/reactos/subsys/win32k/eng/mouse.c index 99ffdeba280..e93767413d5 100644 --- a/reactos/subsys/win32k/eng/mouse.c +++ b/reactos/subsys/win32k/eng/mouse.c @@ -16,7 +16,7 @@ * 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.78 2004/12/12 01:40:36 weiden Exp $ +/* $Id: mouse.c,v 1.79 2004/12/12 17:56:52 weiden Exp $ * * PROJECT: ReactOS kernel * PURPOSE: Mouse @@ -41,7 +41,6 @@ MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1, LONG tmp; GDIDEVICE *ppdev; GDIPOINTER *pgp; - POINTL pt; ASSERT(SurfObj != NULL); @@ -54,7 +53,8 @@ MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1, pgp = &ppdev->Pointer; - if (SPS_ACCEPT_NOEXCLUDE == pgp->Status) + if (SPS_ACCEPT_NOEXCLUDE == pgp->Status || + pgp->Exclude.right == -1) { return(FALSE); } @@ -68,13 +68,10 @@ MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1, tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp; } - pt.x = pgp->Pos.x - pgp->HotSpot.x; - pt.y = pgp->Pos.y - pgp->HotSpot.y; - - if (pt.x + pgp->Size.cx >= HazardX1 - && pt.x <= HazardX2 - && pt.y + pgp->Size.cy >= HazardY1 - && pt.y <= HazardY2) + if (pgp->Exclude.right >= HazardX1 + && pgp->Exclude.left <= HazardX2 + && pgp->Exclude.bottom >= HazardY1 + && pgp->Exclude.top <= HazardY2) { if (0 != pgp->SafetyRemoveCount++) { @@ -110,7 +107,8 @@ MouseSafetyOnDrawEnd(SURFOBJ *SurfObj) pgp = &ppdev->Pointer; - if(SPS_ACCEPT_NOEXCLUDE == pgp->Status) + if(SPS_ACCEPT_NOEXCLUDE == pgp->Status || + pgp->Exclude.right == -1) { return FALSE; } @@ -122,10 +120,16 @@ MouseSafetyOnDrawEnd(SURFOBJ *SurfObj) /* Someone else removed it too, let them restore it */ return FALSE; } + /* FIXME - this is wrong!!!!!! we must NOT access pgp->Pos from here, it's + a private field for ENG/driver. This will paint the cursor to the + wrong screen coordinates when a driver overrides DrvMovePointer()! + We should store the coordinates before calling Drv/EngMovePointer() + and Drv/EngSetPointerShape() separately in the GDIDEVICE structure + or somewhere where ntuser can access it! */ if (pgp->MovePointer) - pgp->MovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, NULL); + pgp->MovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, &pgp->Exclude); else - EngMovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, NULL); + EngMovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, &pgp->Exclude); pgp->SafetySwitch = FALSE; } @@ -152,11 +156,6 @@ IntHideMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface) pgp->Enabled = FALSE; - if(pgp->Pos.x == -1) - { - return; - } - pt.x = pgp->Pos.x - pgp->HotSpot.x; pt.y = pgp->Pos.y - pgp->HotSpot.y; @@ -368,20 +367,15 @@ EngSetPointerShape( pgp->HotSpot.x = xHot; pgp->HotSpot.y = yHot; - pgp->Pos.x = x; - pgp->Pos.y = y; + 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 (prcl != NULL) - { - /* FIXME - right rectangle when x == -1? */ - prcl->left = pgp->Pos.x - pgp->HotSpot.x; - prcl->top = pgp->Pos.y - pgp->HotSpot.x; - prcl->right = prcl->left + pgp->Size.cx; - prcl->bottom = prcl->top + pgp->Size.cy; - } - if (psoColor != NULL) { PBYTE Bits; @@ -474,7 +468,17 @@ EngSetPointerShape( if(x != -1) { IntShowMousePointer(ppdev, pso); + + if (prcl != NULL) + { + prcl->left = pgp->Pos.x - pgp->HotSpot.x; + prcl->top = pgp->Pos.y - pgp->HotSpot.x; + prcl->right = prcl->left + pgp->Size.cx; + prcl->bottom = prcl->top + pgp->Size.cy; + } } + + /* FIXME - touch prcl when x == -1? */ return SPS_ACCEPT_EXCLUDE; } @@ -501,23 +505,22 @@ EngMovePointer( pgp = &ppdev->Pointer; - IntHideMousePointer(ppdev, pso); if (x != -1) { pgp->Pos.x = x; pgp->Pos.y = y; IntShowMousePointer(ppdev, pso); + if (prcl != NULL) + { + prcl->left = pgp->Pos.x - pgp->HotSpot.x; + prcl->top = pgp->Pos.y - pgp->HotSpot.x; + prcl->right = prcl->left + pgp->Size.cx; + prcl->bottom = prcl->top + pgp->Size.cy; + } } - - if (prcl != NULL) - { - /* FIXME - right rectangle when x == -1? */ - prcl->left = pgp->Pos.x - pgp->HotSpot.x; - prcl->top = pgp->Pos.y - pgp->HotSpot.x; - prcl->right = prcl->left + pgp->Size.cx; - prcl->bottom = prcl->top + pgp->Size.cy; - } + + /* FIXME - touch prcl when x == -1? */ } /* EOF */ diff --git a/reactos/subsys/win32k/ntuser/cursoricon.c b/reactos/subsys/win32k/ntuser/cursoricon.c index 5b69597bd5b..57e45d7d8c3 100644 --- a/reactos/subsys/win32k/ntuser/cursoricon.c +++ b/reactos/subsys/win32k/ntuser/cursoricon.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: cursoricon.c,v 1.1 2004/12/12 01:40:38 weiden Exp $ */ +/* $Id: cursoricon.c,v 1.2 2004/12/12 17:56:52 weiden Exp $ */ #include PCURICON_OBJECT FASTCALL @@ -92,6 +92,9 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, /* Remove the cursor if it was displayed */ if (GDIDEV(SurfObj)->Pointer.MovePointer) GDIDEV(SurfObj)->Pointer.MovePointer(SurfObj, -1, -1, NULL); + else + EngMovePointer(SurfObj, -1, -1, NULL); + GDIDEV(SurfObj)->Pointer.Exclude.right = -1; } GDIDEV(SurfObj)->Pointer.Status = SPS_ACCEPT_NOEXCLUDE; diff --git a/reactos/subsys/win32k/ntuser/input.c b/reactos/subsys/win32k/ntuser/input.c index b56e3132ab0..9e4f375b634 100644 --- a/reactos/subsys/win32k/ntuser/input.c +++ b/reactos/subsys/win32k/ntuser/input.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: input.c,v 1.39 2004/12/12 01:40:37 weiden Exp $ +/* $Id: input.c,v 1.40 2004/12/12 17:56:52 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -650,8 +650,13 @@ IntMouseInput(MOUSEINPUT *mi) if (GDIDEV(SurfObj)->Pointer.MovePointer) { - GDIDEV(SurfObj)->Pointer.MovePointer(SurfObj, MousePos.x, MousePos.y, NULL); + GDIDEV(SurfObj)->Pointer.MovePointer(SurfObj, MousePos.x, MousePos.y, &(GDIDEV(SurfObj)->Pointer.Exclude)); } + /* FIXME - That's a bad thing! We should't access private gdi pointer fields + from here. However it is required so MouseSafetyOnDrawEnd() can + properly paint the mouse cursor to the screen again. See the + comment in MouseSafetyOnDrawEnd() to fix this problem! */ + GDIDEV(SurfObj)->Pointer.Pos = MousePos; BITMAPOBJ_UnlockBitmap(hBitmap); } diff --git a/reactos/subsys/win32k/objects/dc.c b/reactos/subsys/win32k/objects/dc.c index d6cfe95e806..af760657bdb 100644 --- a/reactos/subsys/win32k/objects/dc.c +++ b/reactos/subsys/win32k/objects/dc.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: dc.c,v 1.149 2004/12/12 01:40:38 weiden Exp $ +/* $Id: dc.c,v 1.150 2004/12/12 17:56:52 weiden Exp $ * * DC.C - Device context functions * @@ -622,6 +622,8 @@ IntCreatePrimarySurface() DPRINT("Adjusting GDIInfo.ulLogPixelsY\n"); PrimarySurface.GDIInfo.ulLogPixelsY = 96; } + + PrimarySurface.Pointer.Exclude.right = -1; DPRINT("calling completePDev\n"); @@ -659,7 +661,8 @@ IntCreatePrimarySurface() SurfaceRect.left = SurfaceRect.top = 0; SurfaceRect.right = SurfObj->sizlBitmap.cx; SurfaceRect.bottom = SurfObj->sizlBitmap.cy; - EngEraseSurface(SurfObj, &SurfaceRect, 0); + /* FIXME - why does EngEraseSurface() sometimes crash? + EngEraseSurface(SurfObj, &SurfaceRect, 0); */ EngUnlockSurface(SurfObj); IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy); break;