From 5eaa4fda83bd48cf69492f3d0defbfdbd38b1be9 Mon Sep 17 00:00:00 2001 From: Gunnar Dalsnes Date: Sun, 18 Sep 2005 23:06:15 +0000 Subject: [PATCH] -added better LIST_FOR_EACH macros (ripped from wine) and fix their usage -make hotkeys session global (they dont belong in winsta) svn path=/trunk/; revision=17923 --- reactos/include/reactos/helper.h | 21 ++-- reactos/ntoskrnl/fs/filelock.c | 33 ++---- reactos/ntoskrnl/fs/notify.c | 15 ++- reactos/subsys/win32k/include/hotkey.h | 15 ++- reactos/subsys/win32k/include/winsta.h | 1 - reactos/subsys/win32k/main/dllmain.c | 7 ++ reactos/subsys/win32k/ntuser/hotkey.c | 140 +++++++------------------ reactos/subsys/win32k/ntuser/input.c | 5 +- reactos/subsys/win32k/ntuser/winsta.c | 2 - 9 files changed, 88 insertions(+), 151 deletions(-) diff --git a/reactos/include/reactos/helper.h b/reactos/include/reactos/helper.h index b9d4c9f8c49..ea6b90a0ff9 100644 --- a/reactos/include/reactos/helper.h +++ b/reactos/include/reactos/helper.h @@ -17,12 +17,21 @@ #endif #define EXPORTED __declspec(dllexport) #define IMPORTED __declspec(dllimport) -#define LIST_FOR_EACH(entry, head) \ - for(entry = (head)->Flink; entry != (head); entry = entry->Flink) -#define LIST_FOR_EACH_SAFE(tmp_entry, head, ptr, type, field) \ - for ((tmp_entry)=(head)->Flink; (tmp_entry)!=(head) && \ - ((ptr) = CONTAINING_RECORD(tmp_entry,type,field)) && \ - ((tmp_entry) = (tmp_entry)->Flink); ) + +/* iterate through the list using a list entry */ +#define LIST_FOR_EACH(elem, list, type, field) \ + for ((elem) = CONTAINING_RECORD((list)->Flink, type, field); \ + &(elem)->field != (list); \ + (elem) = CONTAINING_RECORD((elem)->field.Flink, type, field)) + +/* iterate through the list using a list entry, with safety against removal */ +#define LIST_FOR_EACH_SAFE(cursor, cursor2, list, type, field) \ + for ((cursor) = CONTAINING_RECORD((list)->Flink, type, field), \ + (cursor2) = CONTAINING_RECORD((cursor)->field.Flink, type, field); \ + &(cursor)->field != (list); \ + (cursor) = (cursor2), \ + (cursor2) = CONTAINING_RECORD((cursor)->field.Flink, type, field)) + #define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a + \ ((PIMAGE_DOS_HEADER)a)->e_lfanew + \ sizeof (IMAGE_NT_SIGNATURE) + \ diff --git a/reactos/ntoskrnl/fs/filelock.c b/reactos/ntoskrnl/fs/filelock.c index e36d8a12a9d..2c5c379f1b3 100644 --- a/reactos/ntoskrnl/fs/filelock.c +++ b/reactos/ntoskrnl/fs/filelock.c @@ -161,7 +161,6 @@ FsRtlpCheckLockForReadOrWriteAccess( KIRQL oldirql; PFILE_LOCK_TOC LockToc; PFILE_LOCK_GRANTED Granted; - PLIST_ENTRY EnumEntry; LARGE_INTEGER EndOffset; ASSERT(FileLock); @@ -177,10 +176,8 @@ FsRtlpCheckLockForReadOrWriteAccess( KeAcquireSpinLock(&LockToc->SpinLock, &oldirql); - LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead) + LIST_FOR_EACH(Granted, &LockToc->GrantedListHead, FILE_LOCK_GRANTED, ListEntry) { - Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED, ListEntry); - //if overlapping if(IsOverlappingLock(&Granted->Lock, FileOffset, &EndOffset)) { @@ -358,12 +355,12 @@ FsRtlpFastUnlockAllByKey( { KIRQL oldirql; PFILE_LOCK_TOC LockToc; - PLIST_ENTRY EnumEntry; - PFILE_LOCK_GRANTED Granted; + PFILE_LOCK_GRANTED Granted, tmp; BOOLEAN Unlock = FALSE; //must make local copy since FILE_LOCK struct is allowed to be paged BOOLEAN GotUnlockRoutine; LIST_ENTRY UnlockedListHead; + PLIST_ENTRY EnumEntry; ASSERT(FileLock); LockToc = FileLock->LockInformation; @@ -377,7 +374,7 @@ FsRtlpFastUnlockAllByKey( GotUnlockRoutine = FileLock->UnlockRoutine != NULL; KeAcquireSpinLock(&LockToc->SpinLock, &oldirql); - LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->GrantedListHead, Granted, FILE_LOCK_GRANTED, ListEntry) + LIST_FOR_EACH_SAFE(Granted, tmp, &LockToc->GrantedListHead, FILE_LOCK_GRANTED, ListEntry) { if (Granted->Lock.Process == Process && @@ -506,17 +503,14 @@ FsRtlpAddLock( IN PVOID Context ) { - PLIST_ENTRY EnumEntry; PFILE_LOCK_GRANTED Granted; LARGE_INTEGER EndOffset; EndOffset.QuadPart = FileOffset->QuadPart + Length->QuadPart - 1; //loop and try to find conflicking locks - LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead) + LIST_FOR_EACH(Granted, &LockToc->GrantedListHead, FILE_LOCK_GRANTED, ListEntry) { - Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED, ListEntry); - if (IsOverlappingLock(&Granted->Lock, FileOffset, &EndOffset)) { //we found a locks that overlap with the new lock @@ -578,13 +572,13 @@ FsRtlpCompletePendingLocks( { //walk pending list, FIFO order, try 2 complete locks PLIST_ENTRY EnumEntry; - PIRP Irp; + PIRP Irp, tmp; PIO_STACK_LOCATION Stack; LIST_ENTRY CompletedListHead; InitializeListHead(&CompletedListHead); - LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->PendingListHead, Irp, IRP, Tail.Overlay.ListEntry) + LIST_FOR_EACH_SAFE(Irp, tmp, &LockToc->PendingListHead, IRP, Tail.Overlay.ListEntry) { Stack = IoGetCurrentIrpStackLocation(Irp); if (FsRtlpAddLock(LockToc, @@ -676,8 +670,7 @@ FsRtlpUnlockSingle( { KIRQL oldirql; PFILE_LOCK_TOC LockToc; - PFILE_LOCK_GRANTED Granted; - PLIST_ENTRY EnumEntry; + PFILE_LOCK_GRANTED Granted, tmp; ASSERT(FileLock); LockToc = FileLock->LockInformation; @@ -689,7 +682,7 @@ FsRtlpUnlockSingle( KeAcquireSpinLock(&LockToc->SpinLock, &oldirql ); - LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->GrantedListHead, Granted,FILE_LOCK_GRANTED,ListEntry) + LIST_FOR_EACH_SAFE(Granted, tmp, &LockToc->GrantedListHead, FILE_LOCK_GRANTED,ListEntry) { //must be exact match @@ -778,7 +771,6 @@ FsRtlpDumpFileLocks( PFILE_LOCK_TOC LockToc; PFILE_LOCK_GRANTED Granted; PIRP Irp; - PLIST_ENTRY EnumEntry; PIO_STACK_LOCATION Stack; ASSERT(FileLock); @@ -794,10 +786,8 @@ FsRtlpDumpFileLocks( KeAcquireSpinLock(&LockToc->SpinLock, &oldirql); - LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead) + LIST_FOR_EACH(Granted, &LockToc->GrantedListHead, FILE_LOCK_GRANTED , ListEntry) { - Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED , ListEntry); - DPRINT1("%s, start: %I64x, len: %I64x, end: %I64x, key: %i, proc: 0x%p, fob: 0x%p\n", Granted->Lock.ExclusiveLock ? "EXCL" : "SHRD", Granted->Lock.StartingByte.QuadPart, @@ -812,9 +802,8 @@ FsRtlpDumpFileLocks( DPRINT1("Dumping pending file locks, FIFO order\n"); - LIST_FOR_EACH(EnumEntry, &LockToc->PendingListHead) + LIST_FOR_EACH(Irp, &LockToc->PendingListHead, IRP , Tail.Overlay.ListEntry) { - Irp = CONTAINING_RECORD(EnumEntry, IRP , Tail.Overlay.ListEntry); Stack = IoGetCurrentIrpStackLocation(Irp); DPRINT1("%s, start: %I64x, len: %I64x, end: %I64x, key: %i, proc: 0x%p, fob: 0x%p\n", diff --git a/reactos/ntoskrnl/fs/notify.c b/reactos/ntoskrnl/fs/notify.c index 7b12ba4cf0a..526f4ad9e89 100644 --- a/reactos/ntoskrnl/fs/notify.c +++ b/reactos/ntoskrnl/fs/notify.c @@ -120,13 +120,10 @@ FsRtlpFindNotifyEntry( PVOID FsContext ) { - PLIST_ENTRY EnumEntry; PNOTIFY_ENTRY NotifyEntry; - LIST_FOR_EACH(EnumEntry, NotifyList) + LIST_FOR_EACH(NotifyEntry, NotifyList, NOTIFY_ENTRY, ListEntry) { - NotifyEntry = CONTAINING_RECORD(EnumEntry, NOTIFY_ENTRY, ListEntry); - if (NotifyEntry->FsContext == FsContext) { return NotifyEntry; @@ -310,15 +307,15 @@ FsRtlpWatchedDirectoryWasDeleted( ) { LIST_ENTRY CompletedListHead; - PLIST_ENTRY EnumEntry, TmpEntry; - PNOTIFY_ENTRY NotifyEntry; + PLIST_ENTRY TmpEntry; + PNOTIFY_ENTRY NotifyEntry, tmp; PIRP Irp; InitializeListHead(&CompletedListHead); ExAcquireFastMutex((PFAST_MUTEX)NotifySync); - LIST_FOR_EACH_SAFE(EnumEntry, NotifyList, NotifyEntry, NOTIFY_ENTRY, ListEntry ) + LIST_FOR_EACH_SAFE(NotifyEntry, tmp, NotifyList, NOTIFY_ENTRY, ListEntry ) { if (NotifyEntry->Fcb == Fcb) { @@ -654,8 +651,8 @@ FsRtlNotifyFullReportChange ( { USHORT FullDirLen; STRING RelativeName; + PNOTIFY_ENTRY NotifyEntry, tmp; PLIST_ENTRY EnumEntry; - PNOTIFY_ENTRY NotifyEntry; PIRP Irp; LIST_ENTRY CompletedListHead; USHORT NameLenU; @@ -676,7 +673,7 @@ FsRtlNotifyFullReportChange ( ExAcquireFastMutex((PFAST_MUTEX)NotifySync); - LIST_FOR_EACH_SAFE(EnumEntry, NotifyList, NotifyEntry, NOTIFY_ENTRY, ListEntry ) + LIST_FOR_EACH_SAFE(NotifyEntry, tmp, NotifyList, NOTIFY_ENTRY, ListEntry ) { ASSERT(NotifyEntry->Unicode == FsRtlpIsUnicodePath(FullTargetName)); diff --git a/reactos/subsys/win32k/include/hotkey.h b/reactos/subsys/win32k/include/hotkey.h index 556e8240fde..9b9c1035cd5 100644 --- a/reactos/subsys/win32k/include/hotkey.h +++ b/reactos/subsys/win32k/include/hotkey.h @@ -15,23 +15,22 @@ typedef struct _HOT_KEY_ITEM } HOT_KEY_ITEM, *PHOT_KEY_ITEM; NTSTATUS FASTCALL -InitHotKeys(PWINSTATION_OBJECT WinStaObject); +InitHotkeyImpl(); -NTSTATUS FASTCALL -CleanupHotKeys(PWINSTATION_OBJECT WinStaObject); +//NTSTATUS FASTCALL +//CleanupHotKeys(PWINSTATION_OBJECT WinStaObject); -BOOL -GetHotKey (PWINSTATION_OBJECT WinStaObject, - UINT fsModifiers, +BOOL FASTCALL +GetHotKey (UINT fsModifiers, UINT vk, struct _ETHREAD **Thread, HWND *hWnd, int *id); -VOID +VOID FASTCALL UnregisterWindowHotKeys(PWINDOW_OBJECT Window); -VOID +VOID FASTCALL UnregisterThreadHotKeys(struct _ETHREAD *Thread); #endif /* _WIN32K_HOTKEY_H */ diff --git a/reactos/subsys/win32k/include/winsta.h b/reactos/subsys/win32k/include/winsta.h index 302ad07ccac..79158f55848 100644 --- a/reactos/subsys/win32k/include/winsta.h +++ b/reactos/subsys/win32k/include/winsta.h @@ -41,7 +41,6 @@ typedef struct _WINSTATION_OBJECT ULONG Flags; struct _DESKTOP_OBJECT* ActiveDesktop; /* FIXME: Clipboard */ - LIST_ENTRY HotKeyListHead; } WINSTATION_OBJECT, *PWINSTATION_OBJECT; extern WINSTATION_OBJECT *InputWindowStation; diff --git a/reactos/subsys/win32k/main/dllmain.c b/reactos/subsys/win32k/main/dllmain.c index 66aa08d1040..7697dbfae35 100644 --- a/reactos/subsys/win32k/main/dllmain.c +++ b/reactos/subsys/win32k/main/dllmain.c @@ -352,6 +352,13 @@ DriverEntry ( return STATUS_UNSUCCESSFUL; } + Status = InitHotkeyImpl(); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to initialize hotkey implementation!\n"); + return STATUS_UNSUCCESSFUL; + } + Status = InitWindowStationImpl(); if (!NT_SUCCESS(Status)) { diff --git a/reactos/subsys/win32k/ntuser/hotkey.c b/reactos/subsys/win32k/ntuser/hotkey.c index fa78374e4e0..c27cf6c8fe5 100644 --- a/reactos/subsys/win32k/ntuser/hotkey.c +++ b/reactos/subsys/win32k/ntuser/hotkey.c @@ -27,6 +27,18 @@ * 02-11-2003 EK Created */ + + +/* + +FIXME: Hotkey notifications are triggered by keyboard input (physical or programatically) +and since only desktops on WinSta0 can recieve input in seems very wrong to allow +windows/threads on destops not belonging to WinSta0 to set hotkeys (recieve notifications). + +-Gunnar +*/ + + /* INCLUDES ******************************************************************/ #include @@ -36,47 +48,40 @@ /* GLOBALS *******************************************************************/ +LIST_ENTRY gHotkeyList; + /* FUNCTIONS *****************************************************************/ NTSTATUS FASTCALL -InitHotKeys(PWINSTATION_OBJECT WinStaObject) +InitHotkeyImpl() { - InitializeListHead(&WinStaObject->HotKeyListHead); + InitializeListHead(&gHotkeyList); return STATUS_SUCCESS; } +#if 0 //not used NTSTATUS FASTCALL -CleanupHotKeys(PWINSTATION_OBJECT WinStaObject) +CleanupHotKeys() { return STATUS_SUCCESS; } +#endif -BOOL -GetHotKey (PWINSTATION_OBJECT WinStaObject, - UINT fsModifiers, +BOOL FASTCALL +GetHotKey (UINT fsModifiers, UINT vk, struct _ETHREAD **Thread, HWND *hWnd, int *id) { - PLIST_ENTRY Entry; PHOT_KEY_ITEM HotKeyItem; - if(!WinStaObject) + LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry) { - return FALSE; - } - - Entry = WinStaObject->HotKeyListHead.Flink; - while (Entry != &WinStaObject->HotKeyListHead) - { - HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD(Entry, - HOT_KEY_ITEM, - ListEntry); if (HotKeyItem->fsModifiers == fsModifiers && HotKeyItem->vk == vk) { @@ -89,37 +94,21 @@ GetHotKey (PWINSTATION_OBJECT WinStaObject, if (id != NULL) *id = HotKeyItem->id; - return TRUE; } - - Entry = Entry->Flink; } return FALSE; } -VOID +VOID FASTCALL UnregisterWindowHotKeys(PWINDOW_OBJECT Window) { - PLIST_ENTRY Entry; - PHOT_KEY_ITEM HotKeyItem; - PWINSTATION_OBJECT WinStaObject = NULL; - - if(Window->OwnerThread && Window->OwnerThread->ThreadsProcess) - WinStaObject = Window->OwnerThread->Tcb.Win32Thread->Desktop->WindowStation; - - if(!WinStaObject) - return; - - Entry = WinStaObject->HotKeyListHead.Flink; - while (Entry != &WinStaObject->HotKeyListHead) + PHOT_KEY_ITEM HotKeyItem, tmp; + + LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry) { - HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry, - HOT_KEY_ITEM, - ListEntry); - Entry = Entry->Flink; if (HotKeyItem->hWnd == Window->hSelf) { RemoveEntryList (&HotKeyItem->ListEntry); @@ -130,26 +119,13 @@ UnregisterWindowHotKeys(PWINDOW_OBJECT Window) } -VOID +VOID FASTCALL UnregisterThreadHotKeys(struct _ETHREAD *Thread) { - PLIST_ENTRY Entry; - PHOT_KEY_ITEM HotKeyItem; - PWINSTATION_OBJECT WinStaObject = NULL; + PHOT_KEY_ITEM HotKeyItem, tmp; - if(Thread->Tcb.Win32Thread && Thread->Tcb.Win32Thread->Desktop) - WinStaObject = Thread->Tcb.Win32Thread->Desktop->WindowStation; - - if(!WinStaObject) - return; - - Entry = WinStaObject->HotKeyListHead.Flink; - while (Entry != &WinStaObject->HotKeyListHead) + LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry) { - HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry, - HOT_KEY_ITEM, - ListEntry); - Entry = Entry->Flink; if (HotKeyItem->Thread == Thread) { RemoveEntryList (&HotKeyItem->ListEntry); @@ -160,27 +136,18 @@ UnregisterThreadHotKeys(struct _ETHREAD *Thread) } -static BOOL -IsHotKey (PWINSTATION_OBJECT WinStaObject, - UINT fsModifiers, - UINT vk) +static +BOOL FASTCALL +IsHotKey (UINT fsModifiers, UINT vk) { - PLIST_ENTRY Entry; PHOT_KEY_ITEM HotKeyItem; - Entry = WinStaObject->HotKeyListHead.Flink; - while (Entry != &WinStaObject->HotKeyListHead) + LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry) { - HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry, - HOT_KEY_ITEM, - ListEntry); - if (HotKeyItem->fsModifiers == fsModifiers && - HotKeyItem->vk == vk) + if (HotKeyItem->fsModifiers == fsModifiers && HotKeyItem->vk == vk) { return TRUE; } - - Entry = Entry->Flink; } return FALSE; @@ -195,7 +162,6 @@ NtUserRegisterHotKey(HWND hWnd, { PHOT_KEY_ITEM HotKeyItem; PWINDOW_OBJECT Window; - PWINSTATION_OBJECT WinStaObject = NULL; PETHREAD HotKeyThread; DECLARE_RETURN(BOOL); @@ -215,17 +181,8 @@ NtUserRegisterHotKey(HWND hWnd, HotKeyThread = Window->OwnerThread; } - - if(HotKeyThread->ThreadsProcess && HotKeyThread->ThreadsProcess->Win32Process) - WinStaObject = HotKeyThread->Tcb.Win32Thread->Desktop->WindowStation; - - if(!WinStaObject) - { - RETURN( FALSE); - } - /* Check for existing hotkey */ - if (IsHotKey (WinStaObject, fsModifiers, vk)) + if (IsHotKey (fsModifiers, vk)) { RETURN( FALSE); } @@ -242,8 +199,7 @@ NtUserRegisterHotKey(HWND hWnd, HotKeyItem->fsModifiers = fsModifiers; HotKeyItem->vk = vk; - InsertHeadList (&WinStaObject->HotKeyListHead, - &HotKeyItem->ListEntry); + InsertHeadList (&gHotkeyList, &HotKeyItem->ListEntry); RETURN( TRUE); @@ -255,13 +211,10 @@ CLEANUP: BOOL STDCALL -NtUserUnregisterHotKey(HWND hWnd, - int id) +NtUserUnregisterHotKey(HWND hWnd, int id) { - PLIST_ENTRY Entry; PHOT_KEY_ITEM HotKeyItem; PWINDOW_OBJECT Window; - PWINSTATION_OBJECT WinStaObject = NULL; DECLARE_RETURN(BOOL); DPRINT("Enter NtUserUnregisterHotKey\n"); @@ -272,30 +225,15 @@ NtUserUnregisterHotKey(HWND hWnd, RETURN( FALSE); } - if(Window->OwnerThread->ThreadsProcess && Window->OwnerThread->ThreadsProcess->Win32Process) - WinStaObject = Window->OwnerThread->Tcb.Win32Thread->Desktop->WindowStation; - - if(!WinStaObject) + LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry) { - RETURN( FALSE); - } - - Entry = WinStaObject->HotKeyListHead.Flink; - while (Entry != &WinStaObject->HotKeyListHead) - { - HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry, - HOT_KEY_ITEM, - ListEntry); - if (HotKeyItem->hWnd == hWnd && - HotKeyItem->id == id) + if (HotKeyItem->hWnd == hWnd && HotKeyItem->id == id) { RemoveEntryList (&HotKeyItem->ListEntry); ExFreePool (HotKeyItem); RETURN( TRUE); } - - Entry = Entry->Flink; } RETURN( FALSE); diff --git a/reactos/subsys/win32k/ntuser/input.c b/reactos/subsys/win32k/ntuser/input.c index e1492a499d1..e020ff288fb 100644 --- a/reactos/subsys/win32k/ntuser/input.c +++ b/reactos/subsys/win32k/ntuser/input.c @@ -642,6 +642,8 @@ KeyboardThreadMain(PVOID StartContext) if(NextKeyInput.MakeCode == 0x2E)/* Ctrl-C */ { DPRINT1("Ctrl-C pressed\n"); + /* FIXME: this seems wrong! this bypass hotkeys and all and the winhellos CRTL+C hotkey test + dont work (anymore) */ co_MsqPostKeyboardMessage(WM_COPY,0,0); continue; } @@ -697,8 +699,7 @@ KeyboardThreadMain(PVOID StartContext) KeyInput.Flags & KEY_E0 ? 0xE0 : (KeyInput.Flags & KEY_E1 ? 0xE1 : 0)); - if (GetHotKey(InputWindowStation, - ModifierState, + if (GetHotKey(ModifierState, msg.wParam, &Thread, &hWnd, diff --git a/reactos/subsys/win32k/ntuser/winsta.c b/reactos/subsys/win32k/ntuser/winsta.c index 6a68e13a0bf..40ab6ffaa8f 100644 --- a/reactos/subsys/win32k/ntuser/winsta.c +++ b/reactos/subsys/win32k/ntuser/winsta.c @@ -535,8 +535,6 @@ NtUserCreateWindowStation( return 0; } - InitHotKeys(WindowStationObject); - CurInfo->Enabled = FALSE; CurInfo->ButtonsDown = 0; CurInfo->CursorClipInfo.IsClipped = FALSE;