1. ClipCursor(), GetClipCursor() in user32

2. NtUserClipCursor() and NtUserGetClipCursor() in win32k
3. moved system cursor information to WINSTATION_OBJECT
4. modified win32k mousedriver callback routine for cursor clipping

svn path=/trunk/; revision=5807
This commit is contained in:
Thomas Bluemel 2003-08-24 01:12:16 +00:00
parent f9212d48c5
commit 53ee161d92
8 changed files with 252 additions and 47 deletions

View file

@ -1,4 +1,4 @@
/* $Id: stubs.c,v 1.36 2003/08/22 00:33:47 weiden Exp $
/* $Id: stubs.c,v 1.37 2003/08/24 01:12:15 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
@ -109,19 +109,6 @@ CheckRadioButton(
}
/*
* @unimplemented
*/
WINBOOL
STDCALL
ClipCursor(
CONST RECT *lpRect)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/

View file

@ -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: cursor.c,v 1.8 2003/07/27 11:54:41 dwelch Exp $
/* $Id: cursor.c,v 1.9 2003/08/24 01:12:15 weiden Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/cursor.c
@ -30,6 +30,7 @@
#include <windows.h>
#include <user32.h>
#include <string.h>
#include <debug.h>
/* FUNCTIONS *****************************************************************/
@ -65,15 +66,27 @@ DestroyCursor(HCURSOR hCursor)
/*
* @unimplemented
* @implemented
*/
WINBOOL STDCALL
GetClipCursor(LPRECT lpRect)
{
UNIMPLEMENTED;
RECT rc;
WINBOOL res;
if(!lpRect)
{
SetLastError(ERROR_NOACCESS);
return FALSE;
}
RtlCopyMemory(&rc, lpRect, sizeof(RECT));
res = NtUserGetClipCursor(&rc);
RtlCopyMemory(lpRect, &rc, sizeof(RECT));
return res;
}
/*
* @unimplemented
@ -159,6 +172,25 @@ LoadCursorW(HINSTANCE hInstance,
}
/*
* @implemented
*/
WINBOOL
STDCALL
ClipCursor(
CONST RECT *lpRect)
{
RECT rc;
if(lpRect)
{
RtlCopyMemory(&rc, lpRect, sizeof(RECT));
return NtUserClipCursor(&rc);
}
else
return NtUserClipCursor(NULL);
}
/*
* @unimplemented
*/

View file

@ -8,6 +8,24 @@
#define NTOS_MODE_KERNEL
#include <ntos.h>
typedef struct _CURSORCLIP_INFO
{
BOOL IsClipped;
UINT Left;
UINT Top;
UINT Right;
UINT Bottom;
} CURSORCLIP_INFO, *PCURSORCLIP_INFO;
typedef struct _SYSTEM_CURSORINFO
{
BOOL Visible;
HANDLE hCursor;
LONG x, y;
LONG cx, cy;
CURSORCLIP_INFO CursorClipInfo;
} SYSTEM_CURSORINFO, *PSYSTEM_CURSORINFO;
typedef struct _WINSTATION_OBJECT
{
CSHORT Type;
@ -19,6 +37,7 @@ typedef struct _WINSTATION_OBJECT
PRTL_ATOM_TABLE AtomTable;
PVOID HandleTable;
HANDLE SystemMenuTemplate;
SYSTEM_CURSORINFO SystemCursor;
struct _DESKTOP_OBJECT* ActiveDesktop;
/* FIXME: Clipboard */
} WINSTATION_OBJECT, *PWINSTATION_OBJECT;

View file

@ -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.29 2003/08/20 07:45:01 gvg Exp $
/* $Id: mouse.c,v 1.30 2003/08/24 01:12:15 weiden Exp $
*
* PROJECT: ReactOS kernel
* PURPOSE: Mouse
@ -45,8 +45,8 @@
static BOOLEAN SafetySwitch = FALSE;
static BOOLEAN SafetySwitch2 = FALSE;
static BOOLEAN MouseEnabled = FALSE;
static LONG mouse_x, mouse_y;
static LONG mouse_width = 0, mouse_height = 0;
//static LONG mouse_x, mouse_y;
//static LONG mouse_width = 0, mouse_height = 0;
static ULONG PointerStatus;
static UCHAR DefaultCursor[256] = {
@ -118,6 +118,24 @@ static UCHAR DefaultCursor[256] = {
/* FUNCTIONS *****************************************************************/
BOOL FASTCALL
CheckClipCursor(LONG *x, LONG *y, PWINSTATION_OBJECT WinSta)
{
if(WinSta->SystemCursor.CursorClipInfo.IsClipped)
{
if(*x > WinSta->SystemCursor.CursorClipInfo.Right)
*x = WinSta->SystemCursor.CursorClipInfo.Right;
if(*x < WinSta->SystemCursor.CursorClipInfo.Left)
*x = WinSta->SystemCursor.CursorClipInfo.Left;
if(*y > WinSta->SystemCursor.CursorClipInfo.Bottom)
*y = WinSta->SystemCursor.CursorClipInfo.Bottom;
if(*y < WinSta->SystemCursor.CursorClipInfo.Top)
*y = WinSta->SystemCursor.CursorClipInfo.Top;
return TRUE;
}
return TRUE;
}
INT STDCALL
MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1,
LONG HazardY1, LONG HazardX2, LONG HazardY2)
@ -128,6 +146,8 @@ MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1,
{
RECTL MouseRect;
LONG tmp;
LONG mouse_x, mouse_y;
LONG mouse_width, mouse_height;
/* Mouse is not allowed to move if GDI is busy drawing */
@ -138,6 +158,16 @@ MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1,
return(FALSE);
}
if(IntGetWindowStationObject(InputWindowStation))
{
mouse_x = InputWindowStation->SystemCursor.x;
mouse_y = InputWindowStation->SystemCursor.y;
mouse_width = InputWindowStation->SystemCursor.cx;
mouse_height = InputWindowStation->SystemCursor.cy;
/* Dereference window station in MouseSafetyOnDrawEnd() */
}
if (SurfObj->iType != STYPE_DEVICE || MouseEnabled == FALSE)
{
return(FALSE);
@ -175,13 +205,19 @@ MouseSafetyOnDrawEnd(PSURFOBJ SurfObj, PSURFGDI SurfGDI)
*/
{
RECTL MouseRect;
LONG mouse_x, mouse_y;
if (SurfObj == NULL)
if ((SurfObj == NULL) || !InputWindowStation)
{
SafetySwitch2 = FALSE;
return(FALSE);
}
mouse_x = InputWindowStation->SystemCursor.x;
mouse_y = InputWindowStation->SystemCursor.y;
ObDereferenceObject(InputWindowStation);
if (SurfObj->iType != STYPE_DEVICE || MouseEnabled == FALSE)
{
SafetySwitch2 = FALSE;
@ -213,6 +249,7 @@ MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
*/
{
ULONG i;
LONG mouse_x, mouse_y, mouse_ox, mouse_oy;
LONG mouse_cx = 0, mouse_cy = 0;
HDC hDC = IntGetScreenDC();
PDC dc;
@ -224,14 +261,24 @@ MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
ULONG TickCount;
static ULONG ButtonsDown = 0;
KeQueryTickCount(&LargeTickCount);
TickCount = LargeTickCount.u.LowPart;
if (hDC == 0)
if ((hDC == 0) || !InputWindowStation)
{
return;
}
if(IntGetWindowStationObject(InputWindowStation))
{
mouse_ox = mouse_x = InputWindowStation->SystemCursor.x;
mouse_oy = mouse_y = InputWindowStation->SystemCursor.y;
ObDereferenceObject(InputWindowStation);
}
else
return;
KeQueryTickCount(&LargeTickCount);
TickCount = LargeTickCount.u.LowPart;
dc = DC_LockDc(hDC);
SurfObj = (PSURFOBJ)AccessUserObject((ULONG) dc->Surface);
SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) dc->Surface);
@ -249,6 +296,13 @@ MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
Msg.time = TickCount;
Msg.pt.x = mouse_x + mouse_cx;
Msg.pt.y = mouse_y + mouse_cy;
if(IntGetWindowStationObject(InputWindowStation))
{
CheckClipCursor(&Msg.pt.x, &Msg.pt.y, InputWindowStation);
ObDereferenceObject(InputWindowStation);
}
if ((0 != Data[i].LastX) || (0 != Data[i].LastY))
{
MsqInsertSystemMessage(&Msg);
@ -295,6 +349,11 @@ MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
/* If the mouse moved then move the pointer. */
if ((mouse_cx != 0 || mouse_cy != 0) && MouseEnabled)
{
if(!IntGetWindowStationObject(InputWindowStation))
{
return;
}
mouse_x += mouse_cx;
mouse_y += mouse_cy;
@ -303,8 +362,15 @@ MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
mouse_x = min(mouse_x, SurfObj->sizlBitmap.cx - 20);
mouse_y = min(mouse_y, SurfObj->sizlBitmap.cy - 20);
CheckClipCursor(&mouse_x, &mouse_y, InputWindowStation);
if (SafetySwitch == FALSE && SafetySwitch2 == FALSE)
InputWindowStation->SystemCursor.x = mouse_x;
InputWindowStation->SystemCursor.y = mouse_y;
ObDereferenceObject(InputWindowStation);
if (SafetySwitch == FALSE && SafetySwitch2 == FALSE &&
((mouse_ox != mouse_x) || (mouse_oy != mouse_y)))
{
SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect);
}
@ -322,31 +388,44 @@ EnableMouse(HDC hDisplayDC)
SIZEL MouseSize;
RECTL MouseRect;
if( hDisplayDC )
if( hDisplayDC && InputWindowStation)
{
if(!IntGetWindowStationObject(InputWindowStation))
{
MouseEnabled = FALSE;
return;
}
dc = DC_LockDc(hDisplayDC);
SurfObj = (PSURFOBJ)AccessUserObject((ULONG) dc->Surface);
SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) dc->Surface);
DC_UnlockDc( hDisplayDC );
/* Create the default mouse cursor. */
mouse_width = 32;
mouse_height = 32;
InputWindowStation->SystemCursor.cx = 32;
InputWindowStation->SystemCursor.cy = 32;
MouseSize.cx = 32;
MouseSize.cy = 64;
hMouseSurf = EngCreateBitmap(MouseSize, 4, BMF_1BPP, BMF_TOPDOWN, DefaultCursor);
MouseSurf = (PSURFOBJ)AccessUserObject((ULONG) hMouseSurf);
/* Tell the display driver to set the pointer shape. */
#if 0
mouse_x = SurfObj->sizlBitmap.cx / 2;
mouse_y = SurfObj->sizlBitmap.cy / 2;
#if 1
InputWindowStation->SystemCursor.x = SurfObj->sizlBitmap.cx / 2;
InputWindowStation->SystemCursor.y = SurfObj->sizlBitmap.cy / 2;
#else
mouse_x = 320;
mouse_y = 240;
InputWindowStation->SystemCursor.x = 320;
InputWindowStation->SystemCursor.y = 240;
#endif
CheckClipCursor(&InputWindowStation->SystemCursor.x,
&InputWindowStation->SystemCursor.y,
InputWindowStation);
ObDereferenceObject(InputWindowStation);
PointerStatus = SurfGDI->SetPointerShape(SurfObj, MouseSurf, NULL, NULL,
0, 0, mouse_x, mouse_y, &MouseRect,
0, 0,
InputWindowStation->SystemCursor.x,
InputWindowStation->SystemCursor.y,
&MouseRect,
SPS_CHANGE);
MouseEnabled = (SPS_ACCEPT_EXCLUDE == PointerStatus ||

View file

@ -2,6 +2,7 @@
#define __WIN32K_MOUSE_H
#include "../eng/misc.h"
#include <include/winsta.h>
//#include <ddk/ntddmou.h>
INT STDCALL MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2);

View file

@ -14,6 +14,8 @@
#define SET_PROCESS_WINDOW_STATION(WinSta) \
((IoGetCurrentProcess()->Win32WindowStation) = (PVOID)(WinSta))
WINSTATION_OBJECT *InputWindowStation;
NTSTATUS FASTCALL
InitWindowStationImpl(VOID);
@ -53,6 +55,9 @@ IntGetCaptureWindow(VOID);
VOID STDCALL
IntSetCaptureWindow(struct _WINDOW_OBJECT* Window);
BOOL FASTCALL
IntGetWindowStationObject(PWINSTATION_OBJECT Object);
#endif /* __WIN32K_WINSTA_H */
/* EOF */

View file

@ -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: winsta.c,v 1.26 2003/08/19 11:48:50 weiden Exp $
/* $Id: winsta.c,v 1.27 2003/08/24 01:12:15 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -62,7 +62,7 @@ STATIC PWNDCLASS_OBJECT DesktopWindowClass;
/* Currently active desktop */
STATIC HDESK InputDesktopHandle = NULL;
STATIC PDESKTOP_OBJECT InputDesktop = NULL;
STATIC PWINSTATION_OBJECT InputWindowStation = NULL;
//STATIC PWINSTATION_OBJECT InputWindowStation = NULL;
static HDC ScreenDeviceContext = NULL;
@ -136,6 +136,8 @@ InitWindowStationImpl(VOID)
NTSTATUS Status;
WNDCLASSEXW wcx;
InputWindowStation = NULL;
/*
* Create the '\Windows\WindowStations' directory
*/
@ -350,6 +352,14 @@ NtUserCreateWindowStation(PUNICODE_STRING lpszWindowStationName,
return((HWINSTA)0);
}
WinStaObject->SystemCursor.Visible = TRUE;
WinStaObject->SystemCursor.hCursor = (HANDLE)0;
WinStaObject->SystemCursor.x = 0;
WinStaObject->SystemCursor.y = 0;
WinStaObject->SystemCursor.cx = 32;
WinStaObject->SystemCursor.cy = 32;
WinStaObject->SystemCursor.CursorClipInfo.IsClipped = FALSE;
DPRINT("Window station successfully created (%wZ)\n", &WindowStationName);
return((HWINSTA)WinSta);
@ -954,4 +964,17 @@ IntDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
}
BOOL FASTCALL
IntGetWindowStationObject(PWINSTATION_OBJECT Object)
{
NTSTATUS Status;
Status = ObReferenceObjectByPointer(Object,
KernelMode,
ExWindowStationObjectType,
0);
return NT_SUCCESS(Status);
}
/* EOF */

View file

@ -1,8 +1,11 @@
#undef WIN32_LEAN_AND_MEAN
#include <win32k/win32k.h>
#include <windows.h>
#include <stdlib.h>
#include <win32k/cursoricon.h>
#include <win32k/bitmaps.h>
#include <include/winsta.h>
#include <include/error.h>
#define NDEBUG
#include <win32k/debug1.h>
@ -218,16 +221,40 @@ NtUserGetCursorInfo(
/*
* @unimplemented
* @implemented
*/
BOOL
STDCALL
NtUserClipCursor(
RECT *lpRect)
{
UNIMPLEMENTED
PWINSTATION_OBJECT WinStaObject;
return 0;
NTSTATUS Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
KernelMode,
0,
&WinStaObject);
if (!NT_SUCCESS(Status))
{
DPRINT("Validation of window station handle (0x%X) failed\n",
PROCESS_WINDOW_STATION());
SetLastWin32Error(Status);
return FALSE;
}
if(lpRect)
{
WinStaObject->SystemCursor.CursorClipInfo.IsClipped = TRUE;
WinStaObject->SystemCursor.CursorClipInfo.Left = lpRect->left;
WinStaObject->SystemCursor.CursorClipInfo.Top = lpRect->top;
WinStaObject->SystemCursor.CursorClipInfo.Right = lpRect->right;
WinStaObject->SystemCursor.CursorClipInfo.Bottom = lpRect->bottom;
}
else
WinStaObject->SystemCursor.CursorClipInfo.IsClipped = FALSE;
ObDereferenceObject(WinStaObject);
return TRUE;
}
@ -263,16 +290,48 @@ NtUserFindExistingCursorIcon(
/*
* @unimplemented
* @implemented
*/
BOOL
STDCALL
NtUserGetClipCursor(
RECT *lpRect)
{
UNIMPLEMENTED
PWINSTATION_OBJECT WinStaObject;
return 0;
if(!lpRect)
return FALSE;
NTSTATUS Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
KernelMode,
0,
&WinStaObject);
if (!NT_SUCCESS(Status))
{
DPRINT("Validation of window station handle (0x%X) failed\n",
PROCESS_WINDOW_STATION());
SetLastWin32Error(Status);
return FALSE;
}
if(WinStaObject->SystemCursor.CursorClipInfo.IsClipped)
{
lpRect->left = WinStaObject->SystemCursor.CursorClipInfo.Left;
lpRect->top = WinStaObject->SystemCursor.CursorClipInfo.Top;
lpRect->right = WinStaObject->SystemCursor.CursorClipInfo.Right;
lpRect->bottom = WinStaObject->SystemCursor.CursorClipInfo.Bottom;
}
else
{
lpRect->left = 0;
lpRect->top = 0;
lpRect->right = NtUserGetSystemMetrics(SM_CXSCREEN);
lpRect->bottom = NtUserGetSystemMetrics(SM_CYSCREEN);
}
ObDereferenceObject(WinStaObject);
return TRUE;
}