From a2b32fbcd65e9485e0837be51c0fd945aa41e64d Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Sun, 8 Aug 2004 17:57:34 +0000 Subject: [PATCH] serialize gui switching and switching the focus message queue svn path=/trunk/; revision=10419 --- reactos/subsys/win32k/include/guicheck.h | 2 ++ reactos/subsys/win32k/include/msgqueue.h | 3 +++ reactos/subsys/win32k/main/dllmain.c | 9 ++++++- reactos/subsys/win32k/ntuser/desktop.c | 20 ++++++++++++-- reactos/subsys/win32k/ntuser/guicheck.c | 33 ++++++++++++++++-------- reactos/subsys/win32k/ntuser/msgqueue.c | 11 +++++++- 6 files changed, 63 insertions(+), 15 deletions(-) diff --git a/reactos/subsys/win32k/include/guicheck.h b/reactos/subsys/win32k/include/guicheck.h index 47003d0142a..5bbb9951d96 100644 --- a/reactos/subsys/win32k/include/guicheck.h +++ b/reactos/subsys/win32k/include/guicheck.h @@ -8,6 +8,8 @@ BOOL FASTCALL IntGraphicsCheck(BOOL Create); BOOL FASTCALL IntCreatePrimarySurface(); VOID FASTCALL IntDestroyPrimarySurface(); +NTSTATUS FASTCALL InitGuiCheckImpl (VOID); + #endif /* _WIN32K_GUICHECK_H */ /* EOF */ diff --git a/reactos/subsys/win32k/include/msgqueue.h b/reactos/subsys/win32k/include/msgqueue.h index ddf4e45d349..a90c5a4dea9 100644 --- a/reactos/subsys/win32k/include/msgqueue.h +++ b/reactos/subsys/win32k/include/msgqueue.h @@ -104,6 +104,9 @@ typedef struct _USER_MESSAGE_QUEUE LIST_ENTRY DispatchingMessagesHead; /* messages that are currently dispatched by this message queue, required for cleanup */ LIST_ENTRY LocalDispatchingMessagesHead; + + /* Desktop that the message queue is attached to */ + struct _DESKTOP_OBJECT *Desktop; } USER_MESSAGE_QUEUE, *PUSER_MESSAGE_QUEUE; BOOL FASTCALL diff --git a/reactos/subsys/win32k/main/dllmain.c b/reactos/subsys/win32k/main/dllmain.c index 4ee84c487bc..85b5c4b8170 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.78 2004/08/02 15:07:26 blight Exp $ +/* $Id: dllmain.c,v 1.79 2004/08/08 17:57:34 weiden Exp $ * * Entry Point for win32k.sys */ @@ -298,6 +298,13 @@ DllMain ( return(Status); } + Status = InitGuiCheckImpl(); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Failed to initialize GUI check implementation.\n"); + return(Status); + } + InitGdiObjectHandleTable (); /* Initialize FreeType library */ diff --git a/reactos/subsys/win32k/ntuser/desktop.c b/reactos/subsys/win32k/ntuser/desktop.c index 8cac7116dab..fa4019b7ce7 100644 --- a/reactos/subsys/win32k/ntuser/desktop.c +++ b/reactos/subsys/win32k/ntuser/desktop.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: desktop.c,v 1.17 2004/07/09 20:57:38 gvg Exp $ + * $Id: desktop.c,v 1.18 2004/08/08 17:57:34 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -186,13 +186,29 @@ IntGetFocusMessageQueue(VOID) VOID FASTCALL IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue) { + PUSER_MESSAGE_QUEUE Old; PDESKTOP_OBJECT pdo = IntGetActiveDesktop(); if (!pdo) { DPRINT("No active desktop\n"); return; } - pdo->ActiveMessageQueue = NewQueue; + if(NewQueue != NULL) + { + if(NewQueue->Desktop != NULL) + { + DPRINT("Message Queue already attached to another desktop!\n"); + return; + } + IntReferenceMessageQueue(NewQueue); + InterlockedExchange((LONG*)&NewQueue->Desktop, (LONG)pdo); + } + Old = (PUSER_MESSAGE_QUEUE)InterlockedExchange((LONG*)&pdo->ActiveMessageQueue, (LONG)NewQueue); + if(Old != NULL) + { + InterlockedExchange((LONG*)&Old->Desktop, 0); + IntDereferenceMessageQueue(Old); + } } HWND FASTCALL IntGetDesktopWindow(VOID) diff --git a/reactos/subsys/win32k/ntuser/guicheck.c b/reactos/subsys/win32k/ntuser/guicheck.c index 62dafcd5e1a..dd19e56bc9c 100644 --- a/reactos/subsys/win32k/ntuser/guicheck.c +++ b/reactos/subsys/win32k/ntuser/guicheck.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: guicheck.c,v 1.19 2004/05/21 10:09:31 weiden Exp $ +/* $Id: guicheck.c,v 1.20 2004/08/08 17:57:34 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -40,7 +40,8 @@ /* GLOBALS *******************************************************************/ -static ULONG NrGuiApplicationsRunning = 0; +static LONG NrGuiAppsRunning = 0; +static FAST_MUTEX GuiSwitchLock; /* FUNCTIONS *****************************************************************/ @@ -48,16 +49,21 @@ static BOOL FASTCALL AddGuiApp(PW32PROCESS W32Data) { W32Data->Flags |= W32PF_CREATEDWINORDC; - if (0 == NrGuiApplicationsRunning++) + if (InterlockedIncrement(&NrGuiAppsRunning) == 1) { - if (! IntInitializeDesktopGraphics()) + BOOL Initialized; + + ExAcquireFastMutex(&GuiSwitchLock); + Initialized = IntInitializeDesktopGraphics(); + ExReleaseFastMutex(&GuiSwitchLock); + + if (!Initialized) { W32Data->Flags &= ~W32PF_CREATEDWINORDC; - NrGuiApplicationsRunning--; + InterlockedDecrement(&NrGuiAppsRunning); return FALSE; } } - return TRUE; } @@ -65,13 +71,11 @@ static void FASTCALL RemoveGuiApp(PW32PROCESS W32Data) { W32Data->Flags &= ~W32PF_CREATEDWINORDC; - if (0 < NrGuiApplicationsRunning) - { - NrGuiApplicationsRunning--; - } - if (0 == NrGuiApplicationsRunning) + if (InterlockedDecrement(&NrGuiAppsRunning) == 0) { + ExAcquireFastMutex(&GuiSwitchLock); IntEndDesktopGraphics(); + ExReleaseFastMutex(&GuiSwitchLock); } } @@ -125,4 +129,11 @@ NtUserManualGuiCheck(LONG Check) } } +NTSTATUS FASTCALL +InitGuiCheckImpl (VOID) +{ + ExInitializeFastMutex(&GuiSwitchLock); + return STATUS_SUCCESS; +} + /* EOF */ diff --git a/reactos/subsys/win32k/ntuser/msgqueue.c b/reactos/subsys/win32k/ntuser/msgqueue.c index 71bd17455c3..d9c3ba06b5f 100644 --- a/reactos/subsys/win32k/ntuser/msgqueue.c +++ b/reactos/subsys/win32k/ntuser/msgqueue.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: msgqueue.c,v 1.102 2004/08/04 22:31:17 weiden Exp $ +/* $Id: msgqueue.c,v 1.103 2004/08/08 17:57:34 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -1223,6 +1223,15 @@ MsqCreateMessageQueue(struct _ETHREAD *Thread) VOID FASTCALL MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) { + PDESKTOP_OBJECT desk; + /* remove the message queue from any desktops */ + if((desk = (PDESKTOP_OBJECT)InterlockedExchange((LONG*)&MessageQueue->Desktop, 0))) + { + InterlockedExchange((LONG*)&desk->ActiveMessageQueue, 0); + IntDereferenceMessageQueue(MessageQueue); + } + + /* clean it up */ MsqCleanupMessageQueue(MessageQueue); /* decrease the reference counter, if it hits zero, the queue will be freed */ IntDereferenceMessageQueue(MessageQueue);