[WIN32CSR] Implement console pausing. [Bug 4739]

svn path=/trunk/; revision=47359
This commit is contained in:
Jeffrey Morlan 2010-05-26 04:57:45 +00:00
parent bbe7ec53c5
commit 1594c9f594
5 changed files with 82 additions and 0 deletions

View file

@ -1467,6 +1467,12 @@ IntWriteConsole(HANDLE hConsoleOutput,
max(sizeof(CSR_API_MESSAGE),
CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + SizeBytes));
if (Status == STATUS_PENDING)
{
WaitForSingleObject(Request->Data.WriteConsoleRequest.UnpauseEvent, INFINITE);
CloseHandle(Request->Data.WriteConsoleRequest.UnpauseEvent);
continue;
}
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
{
RtlFreeHeap(RtlGetProcessHeap(), 0, Request);

View file

@ -62,6 +62,7 @@ typedef struct
BOOL Unicode;
ULONG NrCharactersToWrite;
ULONG NrCharactersWritten;
HANDLE UnpauseEvent;
BYTE Buffer[0];
} CSRSS_WRITE_CONSOLE, *PCSRSS_WRITE_CONSOLE;

View file

@ -849,6 +849,15 @@ CSR_API(CsrWriteConsole)
}
Console = Buff->Header.Console;
if (Console->UnpauseEvent)
{
Status = NtDuplicateObject(GetCurrentProcess(), Console->UnpauseEvent,
ProcessData->Process, &Request->Data.WriteConsoleRequest.UnpauseEvent,
SYNCHRONIZE, 0, 0);
ConioUnlockScreenBuffer(Buff);
return NT_SUCCESS(Status) ? STATUS_PENDING : Status;
}
if(Request->Data.WriteConsoleRequest.Unicode)
{
Length = WideCharToMultiByte(Console->OutputCodePage, 0,
@ -953,6 +962,7 @@ ConioDeleteConsole(Object_t *Object)
}
CloseHandle(Console->ActiveEvent);
if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
DeleteCriticalSection(&Console->Lock);
RtlFreeUnicodeString(&Console->Title);
IntDeleteAllAliases(Console->Aliases);
@ -967,6 +977,26 @@ CsrInitConsoleSupport(VOID)
/* Should call LoadKeyboardLayout */
}
VOID FASTCALL
ConioPause(PCSRSS_CONSOLE Console, UINT Flags)
{
Console->PauseFlags |= Flags;
if (!Console->UnpauseEvent)
Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}
VOID FASTCALL
ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags)
{
Console->PauseFlags &= ~Flags;
if (Console->PauseFlags == 0 && Console->UnpauseEvent)
{
SetEvent(Console->UnpauseEvent);
CloseHandle(Console->UnpauseEvent);
Console->UnpauseEvent = NULL;
}
}
static VOID FASTCALL
ConioProcessChar(PCSRSS_CONSOLE Console,
ConsoleInput *KeyEventRecord)
@ -974,6 +1004,35 @@ ConioProcessChar(PCSRSS_CONSOLE Console,
BOOL updown;
ConsoleInput *TempInput;
if (KeyEventRecord->InputEvent.EventType == KEY_EVENT &&
KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown)
{
WORD vk = KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode;
if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD))
{
DWORD cks = KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState;
if (Console->Mode & ENABLE_LINE_INPUT &&
(vk == VK_PAUSE || (vk == 'S' &&
(cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) &&
!(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)))))
{
ConioPause(Console, PAUSED_FROM_KEYBOARD);
HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
return;
}
}
else
{
if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN &&
vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL)
{
ConioUnpause(Console, PAUSED_FROM_KEYBOARD);
HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
return;
}
}
}
if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT)))
{
switch(KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar)

View file

@ -93,6 +93,8 @@ typedef struct tagCSRSS_CONSOLE
LIST_ENTRY ProcessList;
struct tagALIAS_HEADER *Aliases;
CONSOLE_SELECTION_INFO Selection;
BYTE PauseFlags;
HANDLE UnpauseEvent;
} CSRSS_CONSOLE;
typedef struct ConsoleInput_t
@ -111,10 +113,17 @@ typedef struct ConsoleInput_t
#define CONSOLE_MOUSE_SELECTION 0x4
#define CONSOLE_MOUSE_DOWN 0x8
/* PauseFlags values (internal only) */
#define PAUSED_FROM_KEYBOARD 0x1
#define PAUSED_FROM_SCROLLBAR 0x2
#define PAUSED_FROM_SELECTION 0x4
NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console);
VOID WINAPI ConioDeleteConsole(Object_t *Object);
VOID WINAPI ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer);
VOID WINAPI CsrInitConsoleSupport(VOID);
VOID FASTCALL ConioPause(PCSRSS_CONSOLE Console, UINT Flags);
VOID FASTCALL ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags);
void WINAPI ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode);
PBYTE FASTCALL ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buf, ULONG X, ULONG Y);
VOID FASTCALL ConioDrawConsole(PCSRSS_CONSOLE Console);

View file

@ -844,6 +844,7 @@ GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord)
}
Console->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY;
Console->Selection.srSelection = rc;
ConioPause(Console, PAUSED_FROM_SELECTION);
}
else
{
@ -853,6 +854,7 @@ GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord)
InvalidateRect(hWnd, &oldRect, FALSE);
}
Console->Selection.dwFlags = CONSOLE_NO_SELECTION;
ConioUnpause(Console, PAUSED_FROM_SELECTION);
}
}
@ -1803,6 +1805,11 @@ GuiConsoleHandleScroll(HWND hwnd, UINT uMsg, WPARAM wParam)
case SB_THUMBTRACK:
sInfo.nPos = sInfo.nTrackPos;
ConioPause(Console, PAUSED_FROM_SCROLLBAR);
break;
case SB_THUMBPOSITION:
ConioUnpause(Console, PAUSED_FROM_SCROLLBAR);
break;
case SB_TOP: