diff --git a/reactos/include/napi/win32.h b/reactos/include/napi/win32.h index 77850211837..8cd08936c9d 100644 --- a/reactos/include/napi/win32.h +++ b/reactos/include/napi/win32.h @@ -19,6 +19,8 @@ typedef struct _W32PROCESS LIST_ENTRY MenuListHead; FAST_MUTEX PrivateFontListLock; LIST_ENTRY PrivateFontListHead; + FAST_MUTEX CursorIconListLock; + LIST_ENTRY CursorIconListHead; struct _KBDTABLES* KeyboardLayout; struct _WINSTATION_OBJECT* WindowStation; WORD GDIObjects; diff --git a/reactos/subsys/win32k/eng/mouse.c b/reactos/subsys/win32k/eng/mouse.c index b32b66ced9a..77f7982d03e 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.47 2003/12/07 19:29:33 weiden Exp $ +/* $Id: mouse.c,v 1.48 2003/12/13 22:38:29 weiden Exp $ * * PROJECT: ReactOS kernel * PURPOSE: Mouse @@ -600,13 +600,14 @@ EnableMouse(HDC hDisplayDC) InputWindowStation->SystemCursor.Enabled = FALSE; return; } - IntSetCursor(InputWindowStation, NULL, TRUE); dc = DC_LockDc(hDisplayDC); SurfObj = (PSURFOBJ)AccessUserObject((ULONG) dc->Surface); SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) dc->Surface); DC_UnlockDc( hDisplayDC ); + IntSetCursor(InputWindowStation, NULL, TRUE); + InputWindowStation->SystemCursor.Enabled = (SPS_ACCEPT_EXCLUDE == SurfGDI->PointerStatus || SPS_ACCEPT_NOEXCLUDE == SurfGDI->PointerStatus); diff --git a/reactos/subsys/win32k/include/cursoricon.h b/reactos/subsys/win32k/include/cursoricon.h index 4fa37726e82..75cb0b376fa 100644 --- a/reactos/subsys/win32k/include/cursoricon.h +++ b/reactos/subsys/win32k/include/cursoricon.h @@ -5,7 +5,8 @@ typedef struct _CURICON_OBJECT { - HANDLE Handle; + HANDLE Self; + LIST_ENTRY ListEntry; PW32PROCESS Process; HMODULE hModule; HRSRC hRsrc; @@ -20,6 +21,7 @@ BOOL FASTCALL IntSetupCurIconHandles(PWINSTATION_OBJECT WinStaObject); PCURICON_OBJECT FASTCALL IntGetCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle); VOID FASTCALL IntReleaseCurIconObject(PCURICON_OBJECT Object); PCURICON_OBJECT FASTCALL IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject); +VOID FASTCALL IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Process); #endif /* _WIN32K_CURSORICON_H */ diff --git a/reactos/subsys/win32k/main/dllmain.c b/reactos/subsys/win32k/main/dllmain.c index 7cb86dede6e..aee281f61f0 100644 --- a/reactos/subsys/win32k/main/dllmain.c +++ b/reactos/subsys/win32k/main/dllmain.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: dllmain.c,v 1.61 2003/12/12 23:49:48 weiden Exp $ +/* $Id: dllmain.c,v 1.62 2003/12/13 22:38:29 weiden Exp $ * * Entry Point for win32k.sys */ @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -78,6 +79,9 @@ Win32kProcessCallback (struct _EPROCESS *Process, InitializeListHead(&Win32Process->PrivateFontListHead); ExInitializeFastMutex(&Win32Process->PrivateFontListLock); + + InitializeListHead(&Win32Process->CursorIconListHead); + ExInitializeFastMutex(&Win32Process->CursorIconListLock); Win32Process->KeyboardLayout = W32kGetDefaultKeyLayout(); Win32Process->WindowStation = NULL; @@ -106,6 +110,7 @@ Win32kProcessCallback (struct _EPROCESS *Process, #endif IntRemoveProcessWndProcHandles((HANDLE)Process->UniqueProcessId); IntCleanupMenus(Process, Win32Process); + IntCleanupCurIcons(Process, Win32Process); CleanupForProcess(Process, Process->UniqueProcessId); diff --git a/reactos/subsys/win32k/ntuser/winsta.c b/reactos/subsys/win32k/ntuser/winsta.c index be977d0b137..2b7464562d6 100644 --- a/reactos/subsys/win32k/ntuser/winsta.c +++ b/reactos/subsys/win32k/ntuser/winsta.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: winsta.c,v 1.53 2003/12/13 15:49:32 weiden Exp $ + * $Id: winsta.c,v 1.54 2003/12/13 22:38:29 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -214,7 +214,9 @@ IntInitializeDesktopGraphics(VOID) return FALSE; } DC_SetOwnership(ScreenDeviceContext, NULL); + EnableMouse(ScreenDeviceContext); + /* not the best place to load the cursors but it's good for now */ IntLoadDefaultCursors(FALSE); NtUserAcquireOrReleaseInputOwnership(FALSE); diff --git a/reactos/subsys/win32k/objects/cursoricon.c b/reactos/subsys/win32k/objects/cursoricon.c index 90a6304637f..47409f5892a 100644 --- a/reactos/subsys/win32k/objects/cursoricon.c +++ b/reactos/subsys/win32k/objects/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.37 2003/12/13 19:53:17 weiden Exp $ */ +/* $Id: cursoricon.c,v 1.38 2003/12/13 22:38:29 weiden Exp $ */ #undef WIN32_LEAN_AND_MEAN @@ -108,7 +108,7 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, BOOL Fo OldCursor = CurInfo->CurrentCursorObject; if(OldCursor) { - Ret = (HCURSOR)OldCursor->Handle; + Ret = (HCURSOR)OldCursor->Self; } if(!ForceChange && (OldCursor == NewCursor)) @@ -288,6 +288,7 @@ IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject) PUSER_HANDLE_TABLE HandleTable; PCURICON_OBJECT Object; HANDLE Handle; + PW32PROCESS Win32Process; HandleTable = (PUSER_HANDLE_TABLE)WinStaObject->SystemCursor.CurIconHandleTable; @@ -299,14 +300,20 @@ IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject) return FALSE; } - Object->Handle = Handle; + Win32Process = PsGetWin32Process(); + + ExAcquireFastMutex(&Win32Process->CursorIconListLock); + InsertTailList(&Win32Process->CursorIconListHead, &Object->ListEntry); + ExReleaseFastMutex(&Win32Process->CursorIconListLock); + + Object->Self = Handle; Object->Process = PsGetWin32Process(); return Object; } BOOL FASTCALL -IntDestroyCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle) +IntDestroyCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle, BOOL RemoveFromProcess) { PUSER_HANDLE_TABLE HandleTable; PCURICON_OBJECT Object; @@ -324,13 +331,21 @@ IntDestroyCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle) if(WinStaObject->SystemCursor.CurrentCursorObject == Object) { - ObmDereferenceObject(Object); - return FALSE; + /* Hide the cursor if we're destroying the current cursor */ + IntSetCursor(WinStaObject, NULL, TRUE); } bmpMask = Object->IconInfo.hbmMask; bmpColor = Object->IconInfo.hbmColor; + + if(Object->Process && RemoveFromProcess) + { + ExAcquireFastMutex(&Object->Process->CursorIconListLock); + RemoveEntryList(&Object->ListEntry); + ExReleaseFastMutex(&Object->Process->CursorIconListLock); + } + ObmDereferenceObject(Object); Ret = NT_SUCCESS(ObmCloseHandle(HandleTable, Handle)); @@ -344,6 +359,29 @@ IntDestroyCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle) return Ret; } +VOID FASTCALL +IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Process) +{ + PWINSTATION_OBJECT WinStaObject; + PCURICON_OBJECT Current; + PLIST_ENTRY CurrentEntry, NextEntry; + + if(!(WinStaObject = Win32Process->WindowStation)) + return; + + ExAcquireFastMutex(&Win32Process->CursorIconListLock); + CurrentEntry = Win32Process->CursorIconListHead.Flink; + while(CurrentEntry != &Win32Process->CursorIconListHead) + { + NextEntry = CurrentEntry->Flink; + Current = CONTAINING_RECORD(CurrentEntry, CURICON_OBJECT, ListEntry); + RemoveEntryList(&Current->ListEntry); + IntDestroyCurIconObject(WinStaObject, Current->Self, FALSE); + CurrentEntry = NextEntry; + } + ExReleaseFastMutex(&Win32Process->CursorIconListLock); +} + /* * @implemented */ @@ -371,7 +409,7 @@ NtUserCreateCursorIconHandle(PICONINFO IconInfo, BOOL Indirect) CurIconObject = IntCreateCurIconHandle(WinStaObject); if(CurIconObject) { - Ret = CurIconObject->Handle; + Ret = CurIconObject->Self; if(IconInfo) { @@ -598,7 +636,7 @@ NtUserGetCursorInfo( CursorObject = (PCURICON_OBJECT)CurInfo->CurrentCursorObject; SafeCi.flags = ((CurInfo->ShowingCursor && CursorObject) ? CURSOR_SHOWING : 0); - SafeCi.hCursor = (CursorObject ? (HCURSOR)CursorObject->Handle : (HCURSOR)0); + SafeCi.hCursor = (CursorObject ? (HCURSOR)CursorObject->Self : (HCURSOR)0); SafeCi.ptScreenPos.x = CurInfo->x; SafeCi.ptScreenPos.y = CurInfo->y; @@ -697,7 +735,7 @@ NtUserDestroyCursorIcon( return FALSE; } - if(IntDestroyCurIconObject(WinStaObject, Handle)) + if(IntDestroyCurIconObject(WinStaObject, Handle, TRUE)) { ObDereferenceObject(WinStaObject); return TRUE; @@ -739,7 +777,7 @@ NtUserFindExistingCursorIcon( CurIconObject = IntFindExistingCurIconObject(WinStaObject, hModule, hRsrc, cx, cy); if(CurIconObject) { - Ret = CurIconObject->Handle; + Ret = CurIconObject->Self; IntReleaseCurIconObject(CurIconObject); ObDereferenceObject(WinStaObject);