Author: hbelusca
Date: Mon Sep 8 23:31:12 2014
New Revision: 64085
URL:
http://svn.reactos.org/svn/reactos?rev=64085&view=rev
Log:
[CONSRV]: Use a console input thread that doesn't need any hidden notification window
of any sort.
Modified:
branches/condrv_restructure/win32ss/user/winsrv/consrv/frontends/gui/conwnd.h
branches/condrv_restructure/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/frontends/gui/conwnd.h
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
---
branches/condrv_restructure/win32ss/user/winsrv/consrv/frontends/gui/conwnd.h [iso-8859-1]
(original)
+++
branches/condrv_restructure/win32ss/user/winsrv/consrv/frontends/gui/conwnd.h [iso-8859-1]
Mon Sep 8 23:31:12 2014
@@ -38,6 +38,7 @@
CRITICAL_SECTION Lock;
BOOL WindowSizeLock;
HANDLE hGuiInitEvent;
+ HANDLE hGuiTermEvent;
POINT OldCursor;
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
---
branches/condrv_restructure/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c [iso-8859-1]
(original)
+++
branches/condrv_restructure/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c [iso-8859-1]
Mon Sep 8 23:31:12 2014
@@ -42,7 +42,8 @@
} GUI_INIT_INFO, *PGUI_INIT_INFO;
static BOOL ConsInitialized = FALSE;
-static HWND NotifyWnd = NULL;
+static HANDLE hInputThread = NULL;
+static DWORD dwInputThreadId = 0;
extern HICON ghDefaultIcon;
extern HICON ghDefaultIconSm;
@@ -139,48 +140,59 @@
SwitchFullScreen(PGUI_CONSOLE_DATA GuiData, BOOL FullScreen);
VOID
CreateSysMenu(HWND hWnd);
-static LRESULT CALLBACK
-GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- HWND NewWindow;
- LONG WindowCount;
- MSG Msg;
-
- switch (msg)
- {
- case WM_CREATE:
+
+static DWORD NTAPI
+GuiConsoleInputThread(PVOID Data)
+{
+ PHANDLE GraphicsStartupEvent = (PHANDLE)Data;
+ LONG WindowCount = 0;
+ MSG msg;
+
+ /*
+ * This thread dispatches all the console notifications to the notify window.
+ * It is common for all the console windows.
+ */
+
+ /* The thread has been initialized, set the event */
+ SetEvent(*GraphicsStartupEvent);
+
+ while (GetMessageW(&msg, NULL, 0, 0))
+ {
+ switch (msg.message)
{
- SetWindowLongW(hWnd, GWL_USERDATA, 0);
- return 0;
- }
-
- case PM_CREATE_CONSOLE:
- {
- PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)lParam;
- PCONSRV_CONSOLE Console = GuiData->Console;
- RECT rcWnd;
-
- DPRINT("PM_CREATE_CONSOLE -- creating window\n");
-
- NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE,
- GUI_CONWND_CLASS,
- Console->Title.Buffer,
- WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- NULL,
- ConSrvDllInstance,
- (PVOID)GuiData);
- if (NULL != NewWindow)
+ case PM_CREATE_CONSOLE:
{
+ PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)msg.lParam;
+ PCONSRV_CONSOLE Console = GuiData->Console;
+ HWND NewWindow;
+ RECT rcWnd;
+
+ DPRINT("PM_CREATE_CONSOLE -- creating window\n");
+
+ PrivateCsrssManualGuiCheck(-1); // co_AddGuiApp
+
+ NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE,
+ GUI_CONWND_CLASS,
+ Console->Title.Buffer,
+ WS_OVERLAPPEDWINDOW | WS_HSCROLL |
WS_VSCROLL,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ NULL,
+ NULL,
+ ConSrvDllInstance,
+ (PVOID)GuiData);
+ if (NewWindow == NULL)
+ {
+ DPRINT1("Failed to create a new console window\n");
+ PrivateCsrssManualGuiCheck(+1); // RemoveGuiApp
+ continue;
+ }
+
ASSERT(NewWindow == GuiData->hWindow);
- WindowCount = GetWindowLongW(hWnd, GWL_USERDATA);
- WindowCount++;
- SetWindowLongW(hWnd, GWL_USERDATA, WindowCount);
+ InterlockedIncrement(&WindowCount);
//
// FIXME: TODO: Move everything there into conwnd.c!OnNcCreate()
@@ -205,99 +217,60 @@
if (GuiData->GuiInfo.FullScreen) SwitchFullScreen(GuiData, TRUE);
DPRINT("PM_CREATE_CONSOLE -- showing window\n");
- // ShowWindow(NewWindow, (int)wParam);
- ShowWindowAsync(NewWindow, (int)wParam);
+ // ShowWindow(NewWindow, (int)GuiData->GuiInfo.ShowWindow);
+ ShowWindowAsync(NewWindow, (int)GuiData->GuiInfo.ShowWindow);
DPRINT("Window showed\n");
+
+ continue;
}
- return (LRESULT)NewWindow;
+ case PM_DESTROY_CONSOLE:
+ {
+ PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)msg.lParam;
+ MSG TempMsg;
+
+ /* Exit the full screen mode if it was already set */
+ // LeaveFullScreen(GuiData);
+
+ /*
+ * Window creation is done using a PostMessage(), so it's possible
+ * that the window that we want to destroy doesn't exist yet.
+ * So first empty the message queue.
+ */
+ /*
+ while (PeekMessageW(&TempMsg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&TempMsg);
+ DispatchMessageW(&TempMsg);
+ }*/
+ while (PeekMessageW(&TempMsg, NULL, 0, 0, PM_REMOVE)) ;
+
+ if (GuiData->hWindow == NULL) continue;
+
+ DestroyWindow(GuiData->hWindow);
+ PrivateCsrssManualGuiCheck(+1); // RemoveGuiApp
+
+ SetEvent(GuiData->hGuiTermEvent);
+
+ if (InterlockedDecrement(&WindowCount) == 0)
+ {
+ DPRINT("CONSRV: Going to quit the Input Thread!!\n");
+ goto Quit;
+ }
+
+ continue;
+ }
}
- case PM_DESTROY_CONSOLE:
- {
- PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)lParam;
-
- /* Exit the full screen mode if it was already set */
- // LeaveFullScreen(GuiData);
-
- /*
- * Window creation is done using a PostMessage(), so it's possible
- * that the window that we want to destroy doesn't exist yet.
- * So first empty the message queue.
- */
- /*
- while (PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
- {
- TranslateMessage(&Msg);
- DispatchMessageW(&Msg);
- }*/
- while (PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE)) ;
-
- if (GuiData->hWindow != NULL) /* &&
DestroyWindow(GuiData->hWindow) */
- {
- DestroyWindow(GuiData->hWindow);
-
- WindowCount = GetWindowLongW(hWnd, GWL_USERDATA);
- WindowCount--;
- SetWindowLongW(hWnd, GWL_USERDATA, WindowCount);
- if (0 == WindowCount)
- {
- NotifyWnd = NULL;
- DestroyWindow(hWnd);
- DPRINT("CONSRV: Going to quit the Gui Thread!!\n");
- PostQuitMessage(0);
- }
- }
-
- return 0;
- }
-
- default:
- return DefWindowProcW(hWnd, msg, wParam, lParam);
- }
-}
-
-static DWORD NTAPI
-GuiConsoleGuiThread(PVOID Data)
-{
- MSG msg;
- PHANDLE GraphicsStartupEvent = (PHANDLE)Data;
-
- /*
- * This thread dispatches all the console notifications to the notify window.
- * It is common for all the console windows.
- */
-
- PrivateCsrssManualGuiCheck(+1);
-
- NotifyWnd = CreateWindowW(L"ConSrvCreateNotify",
- L"",
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- NULL,
- ConSrvDllInstance,
- NULL);
- if (NULL == NotifyWnd)
- {
- PrivateCsrssManualGuiCheck(-1);
- SetEvent(*GraphicsStartupEvent);
- return 1;
- }
-
- SetEvent(*GraphicsStartupEvent);
-
- while (GetMessageW(&msg, NULL, 0, 0))
- {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
- DPRINT("CONSRV: Quit the Gui Thread!!\n");
- PrivateCsrssManualGuiCheck(-1);
+Quit:
+ DPRINT("CONSRV: Quit the Input Thread!!\n");
+
+ hInputThread = NULL;
+ dwInputThreadId = 0;
return 1;
}
@@ -305,83 +278,49 @@
static BOOL
GuiInit(VOID)
{
- WNDCLASSEXW wc;
-
/* Exit if we were already initialized */
// if (ConsInitialized) return TRUE;
/*
- * Initialize and register the different window classes, if needed.
+ * Initialize and register the console window class, if needed.
*/
if (!ConsInitialized)
{
- /* Initialize the notification window class */
- wc.cbSize = sizeof(WNDCLASSEXW);
- wc.lpszClassName = L"ConSrvCreateNotify";
- wc.lpfnWndProc = GuiConsoleNotifyWndProc;
- wc.style = 0;
- wc.hInstance = ConSrvDllInstance;
- wc.hIcon = NULL;
- wc.hIconSm = NULL;
- wc.hCursor = NULL;
- wc.hbrBackground = NULL;
- wc.lpszMenuName = NULL;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- if (RegisterClassExW(&wc) == 0)
+ if (!RegisterConWndClass(ConSrvDllInstance)) return FALSE;
+ ConsInitialized = TRUE;
+ }
+
+ /*
+ * Set-up the console input thread
+ */
+ if (hInputThread == NULL)
+ {
+ HANDLE GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+ if (GraphicsStartupEvent == NULL) return FALSE;
+
+ hInputThread = CreateThread(NULL,
+ 0,
+ GuiConsoleInputThread,
+ (PVOID)&GraphicsStartupEvent,
+ 0,
+ &dwInputThreadId);
+ if (hInputThread == NULL)
{
- DPRINT1("Failed to register GUI notify wndproc\n");
+ CloseHandle(GraphicsStartupEvent);
+ DPRINT1("CONSRV: Failed to create graphics console thread.\n");
return FALSE;
}
-
- /* Initialize the console window class */
- if (!RegisterConWndClass(ConSrvDllInstance))
- return FALSE;
-
- ConsInitialized = TRUE;
- }
-
- /*
- * Set-up the notification window
- */
- if (NULL == NotifyWnd)
- {
- HANDLE ThreadHandle;
- HANDLE GraphicsStartupEvent;
-
- GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
- if (NULL == GraphicsStartupEvent) return FALSE;
-
- ThreadHandle = CreateThread(NULL,
- 0,
- GuiConsoleGuiThread,
- (PVOID)&GraphicsStartupEvent,
- 0,
- NULL);
- if (NULL == ThreadHandle)
- {
- CloseHandle(GraphicsStartupEvent);
- DPRINT1("CONSRV: Failed to create graphics console thread. Expect
problems\n");
- return FALSE;
- }
- SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST);
- CloseHandle(ThreadHandle);
+ SetThreadPriority(hInputThread, THREAD_PRIORITY_HIGHEST);
+ CloseHandle(hInputThread);
WaitForSingleObject(GraphicsStartupEvent, INFINITE);
CloseHandle(GraphicsStartupEvent);
-
- if (NULL == NotifyWnd)
- {
- DPRINT1("CONSRV: Failed to create notification window.\n");
- return FALSE;
- }
}
// ConsInitialized = TRUE;
return TRUE;
}
-
/******************************************************************************
@@ -524,6 +463,11 @@
GuiData->LineSelection = FALSE; // Default to block selection
// TODO: Retrieve the selection mode via the registry.
+ /* Finally, finish to initialize the frontend structure */
+ This->Data = GuiData;
+ if (This->OldData) ConsoleFreeHeap(This->OldData);
+ This->OldData = NULL;
+
/*
* We need to wait until the GUI has been fully initialized
* to retrieve custom settings i.e. WindowSize etc...
@@ -531,11 +475,12 @@
* yet implemented.
*/
GuiData->hGuiInitEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+ GuiData->hGuiTermEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
DPRINT("GUI - Checkpoint\n");
/* Create the terminal window */
- PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, GuiData->GuiInfo.ShowWindow,
(LPARAM)GuiData);
+ PostThreadMessageW(dwInputThreadId, PM_CREATE_CONSOLE, 0, (LPARAM)GuiData);
/* Wait until initialization has finished */
WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE);
@@ -551,11 +496,6 @@
return STATUS_UNSUCCESSFUL;
}
- /* Finally, finish to initialize the frontend structure */
- This->Data = GuiData;
- if (This->OldData) ConsoleFreeHeap(This->OldData);
- This->OldData = NULL;
-
return STATUS_SUCCESS;
}
@@ -564,7 +504,12 @@
{
PGUI_CONSOLE_DATA GuiData = This->Data;
- SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM)GuiData);
+ DPRINT("Send PM_DESTROY_CONSOLE message and wait on hGuiTermEvent...\n");
+ PostThreadMessageW(dwInputThreadId, PM_DESTROY_CONSOLE, 0, (LPARAM)GuiData);
+ WaitForSingleObject(GuiData->hGuiTermEvent, INFINITE);
+ DPRINT("hGuiTermEvent set\n");
+ CloseHandle(GuiData->hGuiTermEvent);
+ GuiData->hGuiTermEvent = NULL;
DPRINT("Destroying icons !! - GuiData->hIcon = 0x%p ; ghDefaultIcon = 0x%p ;
GuiData->hIconSm = 0x%p ; ghDefaultIconSm = 0x%p\n",
GuiData->hIcon, ghDefaultIcon, GuiData->hIconSm, ghDefaultIconSm);
@@ -1116,10 +1061,10 @@
if (GuiInitInfo == NULL) return STATUS_NO_MEMORY;
// HACK: We suppose that the pointers will be valid in GuiInitFrontEnd...
+ // If not, then copy exactly what we need in GuiInitInfo.
GuiInitInfo->ConsoleInfo = ConsoleInfo;
GuiInitInfo->ConsoleStartInfo = ConsoleInitInfo->ConsoleStartInfo;
GuiInitInfo->ProcessId = ProcessId;
-
/* Finally, initialize the frontend structure */
FrontEnd->Vtbl = &GuiVtbl;