mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
Reworked console code to use frame buffers and input queues
svn path=/trunk/; revision=1552
This commit is contained in:
parent
5d6f1d7dfa
commit
f353289fba
7 changed files with 594 additions and 336 deletions
|
@ -27,7 +27,8 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE InputHandle;
|
||||
HANDLE OutputHandle;
|
||||
} CSRSS_CREATE_PROCESS_REPLY, *PCSRSS_CREATE_PROCESS_REPLY;
|
||||
|
||||
typedef struct
|
||||
|
@ -45,7 +46,8 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG NrCharactersToRead;
|
||||
WORD NrCharactersToRead;
|
||||
WORD nCharsCanBeDeleted; // number of chars already in buffer that can be backspaced
|
||||
} CSRSS_READ_CONSOLE_REQUEST, *PCSRSS_READ_CONSOLE_REQUEST;
|
||||
|
||||
typedef struct
|
||||
|
@ -57,7 +59,8 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE InputHandle;
|
||||
HANDLE OutputHandle;
|
||||
} CSRSS_ALLOC_CONSOLE_REPLY, *PCSRSS_ALLOC_CONSOLE_REPLY;
|
||||
|
||||
typedef struct
|
||||
|
@ -168,6 +171,21 @@ typedef struct
|
|||
DWORD ConsoleMode;
|
||||
} CSRSS_GET_CONSOLE_MODE_REPLY, *PCSRSS_GET_CONSOLE_MODE_REPLY;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* may want to add some parameters here someday */
|
||||
} CSRSS_CREATE_SCREEN_BUFFER_REQUEST, *PCSRSS_CREATE_SCREEN_BUFFER_REQUEST;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HANDLE OutputHandle; /* handle to newly created screen buffer */
|
||||
} CSRSS_CREATE_SCREEN_BUFFER_REPLY, *PCSRSS_CREATE_SCREEN_BUFFER_REPLY;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HANDLE OutputHandle; /* handle to screen buffer to switch to */
|
||||
} CSRSS_SET_ACTIVE_SCREEN_BUFFER_REQUEST, *PCSRSS_SET_ACTIVE_SCREEN_BUFFER_REQUEST;
|
||||
|
||||
#define CSRSS_MAX_WRITE_CONSOLE_REQUEST (MAX_MESSAGE_DATA - sizeof( ULONG ) - sizeof( CSRSS_WRITE_CONSOLE_REQUEST))
|
||||
#define CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR (MAX_MESSAGE_DATA - sizeof( ULONG ) - sizeof( CSRSS_WRITE_CONSOLE_OUTPUT_CHAR_REQUEST ))
|
||||
|
||||
|
@ -194,6 +212,8 @@ typedef struct
|
|||
#define CSRSS_SET_ATTRIB (0x10)
|
||||
#define CSRSS_GET_MODE (0x11)
|
||||
#define CSRSS_SET_MODE (0x12)
|
||||
#define CSRSS_CREATE_SCREEN_BUFFER (0x13)
|
||||
#define CSRSS_SET_SCREEN_BUFFER (0x14)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -217,6 +237,8 @@ typedef struct
|
|||
CSRSS_SET_ATTRIB_REQUEST SetAttribRequest;
|
||||
CSRSS_SET_CONSOLE_MODE_REQUEST SetConsoleModeRequest;
|
||||
CSRSS_GET_CONSOLE_MODE_REQUEST GetConsoleModeRequest;
|
||||
CSRSS_CREATE_SCREEN_BUFFER_REQUEST CreateScreenBufferRequest;
|
||||
CSRSS_SET_ACTIVE_SCREEN_BUFFER_REQUEST SetActiveScreenBufferRequest;
|
||||
} Data;
|
||||
} CSRSS_API_REQUEST, *PCSRSS_API_REQUEST;
|
||||
|
||||
|
@ -237,6 +259,7 @@ typedef struct
|
|||
CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB_REPLY WriteConsoleOutputAttribReply;
|
||||
CSRSS_GET_CURSOR_INFO_REPLY GetCursorInfoReply;
|
||||
CSRSS_GET_CONSOLE_MODE_REPLY GetConsoleModeReply;
|
||||
CSRSS_CREATE_SCREEN_BUFFER_REPLY CreateScreenBufferReply;
|
||||
} Data;
|
||||
} CSRSS_API_REPLY, *PCSRSS_API_REPLY;
|
||||
|
||||
|
|
|
@ -19,9 +19,10 @@
|
|||
#define ENABLE_PROCESSED_INPUT (0x01)
|
||||
#define ENABLE_WINDOW_INPUT (0x08)
|
||||
#define ENABLE_MOUSE_INPUT (0x0f)
|
||||
#define CONSOLE_MODE_VALID (0x1f)
|
||||
#define CONSOLE_INPUT_MODE_VALID (0x0f)
|
||||
#define ENABLE_PROCESSED_OUTPUT (0x01)
|
||||
#define ENABLE_WRAP_AT_EOL_OUTPUT (0x02)
|
||||
#define CONSOLE_OUTPUT_MODE_VALID (0x03)
|
||||
|
||||
typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
|
||||
COORD dwSize;
|
||||
|
|
|
@ -4,37 +4,64 @@
|
|||
|
||||
/* Object type magic numbers */
|
||||
|
||||
#define CSRSS_CONSOLE_MAGIC 1
|
||||
#define CSRSS_CONSOLE_MAGIC 1
|
||||
#define CSRSS_SCREEN_BUFFER_MAGIC 2
|
||||
|
||||
typedef struct Object_tt
|
||||
{
|
||||
DWORD Type;
|
||||
DWORD ReferenceCount;
|
||||
LONG Type;
|
||||
LONG ReferenceCount;
|
||||
} Object_t;
|
||||
|
||||
typedef struct ConsoleInput_t
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
INPUT_RECORD InputEvent;
|
||||
BOOLEAN Echoed; // already been echoed or not
|
||||
} ConsoleInput;
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Screen buffer structure represents the win32 screen buffer object. *
|
||||
* Internally, the portion of the buffer being shown CAN loop past the *
|
||||
* bottom of the virtual buffer and wrap around to the top. Win32 does *
|
||||
* not do this. I decided to do this because it eliminates the need to *
|
||||
* do a massive memcpy() to scroll the contents of the buffer up to *
|
||||
* scroll the screen on output, instead I just shift down the position *
|
||||
* to be displayed, and let it wrap around to the top again. *
|
||||
* The VirtualX member keeps track of the top X coord that win32 *
|
||||
* clients THINK is currently being displayed, because they think that *
|
||||
* when the display reaches the bottom of the buffer and another line *
|
||||
* being printed causes another line to scroll down, that the buffer IS *
|
||||
* memcpy()'s up, and the bottom of the buffer is still displayed, but *
|
||||
* internally, I just wrap back to the top of the buffer. *
|
||||
***********************************************************************/
|
||||
|
||||
typedef struct CSRSS_SCREEN_BUFFER_t
|
||||
{
|
||||
Object_t Header; /* Object header */
|
||||
BYTE *Buffer; /* pointer to screen buffer */
|
||||
USHORT MaxX, MaxY; /* size of the entire scrollback buffer */
|
||||
USHORT ShowX, ShowY; /* beginning offset for the actual display area */
|
||||
ULONG CurrentX; /* Current X cursor position */
|
||||
ULONG CurrentY; /* Current Y cursor position */
|
||||
BYTE DefaultAttrib; /* default char attribute */
|
||||
USHORT VirtualX; /* top row of buffer being displayed, reported to callers */
|
||||
CONSOLE_CURSOR_INFO CursorInfo;
|
||||
USHORT Mode;
|
||||
} CSRSS_SCREEN_BUFFER, *PCSRSS_SCREEN_BUFFER;
|
||||
|
||||
typedef struct CSRSS_CONSOLE_t
|
||||
{
|
||||
DWORD Type;
|
||||
DWORD ReferenceCount; /* Inherited from Object_t */
|
||||
struct CSRSS_CONSOLE_t *Prev, *Next; /* Next and Prev consoles in console wheel */
|
||||
Object_t Header; /* Object header */
|
||||
struct CSRSS_CONSOLE_t *Prev, *Next; /* Next and Prev consoles in console wheel */
|
||||
HANDLE ActiveEvent;
|
||||
BYTE *Buffer;
|
||||
USHORT MaxX, MaxY; /* size of the entire scrollback buffer */
|
||||
USHORT ShowX, ShowY; /* beginning offset for the actual display area */
|
||||
ULONG CurrentX;
|
||||
ULONG CurrentY;
|
||||
BYTE DefaultAttrib; /* default char attribute */
|
||||
LIST_ENTRY InputEvents; /* List head for input event queue */
|
||||
CONSOLE_CURSOR_INFO CursorInfo;
|
||||
DWORD ConsoleMode;
|
||||
LIST_ENTRY InputEvents; /* List head for input event queue */
|
||||
WORD WaitingChars;
|
||||
WORD WaitingLines; /* number of chars and lines in input queue */
|
||||
WORD WaitingLines; /* number of chars and lines in input queue */
|
||||
PCSRSS_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */
|
||||
WORD Mode; /* Console mode flags */
|
||||
WORD EchoCount; /* count of chars to echo, in line buffered mode */
|
||||
} CSRSS_CONSOLE, *PCSRSS_CONSOLE;
|
||||
|
||||
typedef struct
|
||||
|
@ -101,6 +128,10 @@ NTSTATUS CsrSetConsoleMode( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST
|
|||
|
||||
NTSTATUS CsrGetConsoleMode( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply );
|
||||
|
||||
NTSTATUS CsrCreateScreenBuffer( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply );
|
||||
|
||||
NTSTATUS CsrSetScreenBuffer( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply );
|
||||
|
||||
/* print.c */
|
||||
VOID DisplayString(LPCWSTR lpwString);
|
||||
VOID PrintString (char* fmt, ...);
|
||||
|
@ -112,9 +143,10 @@ VOID Console_Api( DWORD Ignored );
|
|||
extern HANDLE CsrssApiHeap;
|
||||
|
||||
/* api/conio.c */
|
||||
NTSTATUS CsrInitConsole(PCSRSS_PROCESS_DATA ProcessData,
|
||||
PCSRSS_CONSOLE Console);
|
||||
VOID CsrDeleteConsole( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE Console );
|
||||
NTSTATUS CsrInitConsole(PCSRSS_CONSOLE Console);
|
||||
VOID CsrDeleteConsole( PCSRSS_CONSOLE Console );
|
||||
VOID CsrDeleteScreenBuffer( PCSRSS_SCREEN_BUFFER Buffer );
|
||||
NTSTATUS CsrInitConsoleScreenBuffer( PCSRSS_SCREEN_BUFFER Console );
|
||||
VOID CsrInitConsoleSupport(VOID);
|
||||
|
||||
/* api/process.c */
|
||||
|
@ -127,8 +159,5 @@ NTSTATUS CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t
|
|||
BOOL STDCALL CsrServerInitialization (ULONG ArgumentCount,
|
||||
PWSTR *ArgumentArray);
|
||||
NTSTATUS CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object );
|
||||
VOID CsrDrawConsole( PCSRSS_CONSOLE Console );
|
||||
|
||||
|
||||
|
||||
|
||||
VOID CsrDrawConsole( PCSRSS_SCREEN_BUFFER Console );
|
||||
NTSTATUS CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWORD Length, BOOL Attrib );
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
|||
/* $Id: handle.c,v 1.7 2000/05/26 05:40:20 phreak Exp $
|
||||
/* $Id: handle.c,v 1.8 2001/01/21 00:11:54 phreak Exp $
|
||||
*
|
||||
* reactos/subsys/csrss/api/handle.c
|
||||
*
|
||||
|
@ -35,15 +35,16 @@ NTSTATUS CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
|
|||
HANDLE Handle)
|
||||
{
|
||||
Object_t *Object;
|
||||
// DbgPrint( "CsrReleaseObject\n" );
|
||||
if( (((ULONG)Handle) >> 2) - 1 > ProcessData->HandleTableSize || ProcessData->HandleTable[(((ULONG)Handle) >> 2) - 1] == 0 )
|
||||
return STATUS_INVALID_HANDLE;
|
||||
/* dec ref count */
|
||||
Object = ProcessData->HandleTable[(((ULONG)Handle) >> 2) - 1];
|
||||
if( --Object->ReferenceCount == 0 )
|
||||
if( InterlockedDecrement( &Object->ReferenceCount ) == 0 )
|
||||
switch( Object->Type )
|
||||
{
|
||||
case CSRSS_CONSOLE_MAGIC: CsrDeleteConsole( ProcessData, (PCSRSS_CONSOLE) Object );
|
||||
case CSRSS_CONSOLE_MAGIC: CsrDeleteConsole( (PCSRSS_CONSOLE) Object );
|
||||
break;
|
||||
case CSRSS_SCREEN_BUFFER_MAGIC: CsrDeleteScreenBuffer( (PCSRSS_SCREEN_BUFFER) Object );
|
||||
break;
|
||||
default: DbgPrint( "CSR: Error: releaseing unknown object type" );
|
||||
}
|
||||
|
@ -56,14 +57,13 @@ NTSTATUS CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Objec
|
|||
ULONG i;
|
||||
PVOID* NewBlock;
|
||||
|
||||
// DbgPrint( "CsrInsertObject\n" );
|
||||
for (i = 0; i < ProcessData->HandleTableSize; i++)
|
||||
{
|
||||
if (ProcessData->HandleTable[i] == NULL)
|
||||
{
|
||||
ProcessData->HandleTable[i] = Object;
|
||||
*Handle = (HANDLE)(((i + 1) << 2) | 0x3);
|
||||
Object->ReferenceCount++;
|
||||
InterlockedIncrement( &Object->ReferenceCount );
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ NTSTATUS CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Objec
|
|||
ProcessData->HandleTable = (Object_t **)NewBlock;
|
||||
ProcessData->HandleTable[i] = Object;
|
||||
*Handle = (HANDLE)(((i + 1) << 2) | 0x3);
|
||||
Object->ReferenceCount++;
|
||||
InterlockedIncrement( &Object->ReferenceCount );
|
||||
ProcessData->HandleTableSize = ProcessData->HandleTableSize + 64;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: process.c,v 1.10 2000/07/04 11:11:06 dwelch Exp $
|
||||
/* $Id: process.c,v 1.11 2001/01/21 00:11:54 phreak Exp $
|
||||
*
|
||||
* reactos/subsys/csrss/api/process.c
|
||||
*
|
||||
|
@ -90,13 +90,8 @@ NTSTATUS CsrFreeProcessData( ULONG Pid )
|
|||
}
|
||||
if( ProcessData[i]->Console )
|
||||
{
|
||||
RtlEnterCriticalSection( &ActiveConsoleLock );
|
||||
if( --ProcessData[i]->Console->ReferenceCount == 0 )
|
||||
{
|
||||
RtlLeaveCriticalSection( &ActiveConsoleLock );
|
||||
CsrDeleteConsole( ProcessData[i], ProcessData[i]->Console );
|
||||
}
|
||||
RtlLeaveCriticalSection( &ActiveConsoleLock );
|
||||
if( InterlockedDecrement( &(ProcessData[i]->Console->Header.ReferenceCount) ) == 0 )
|
||||
CsrDeleteConsole( ProcessData[i]->Console );
|
||||
}
|
||||
RtlFreeHeap( CsrssApiHeap, 0, ProcessData[i] );
|
||||
ProcessData[i] = 0;
|
||||
|
@ -139,30 +134,37 @@ NTSTATUS CsrCreateProcess (PCSRSS_PROCESS_DATA ProcessData,
|
|||
Console = RtlAllocateHeap(CsrssApiHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(CSRSS_CONSOLE));
|
||||
CsrInitConsole(ProcessData,
|
||||
Console);
|
||||
Status = CsrInitConsole(Console);
|
||||
if( !NT_SUCCESS( Status ) )
|
||||
{
|
||||
CsrFreeProcessData( NewProcessData->ProcessId );
|
||||
Reply->Status = Status;
|
||||
return Status;
|
||||
}
|
||||
NewProcessData->Console = Console;
|
||||
Console->ReferenceCount++;
|
||||
Console->Header.ReferenceCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewProcessData->Console = ProcessData->Console;
|
||||
RtlEnterCriticalSection( &ActiveConsoleLock );
|
||||
ProcessData->Console->ReferenceCount++;
|
||||
RtlLeaveCriticalSection( &ActiveConsoleLock );
|
||||
InterlockedIncrement( &(ProcessData->Console->Header.ReferenceCount) );
|
||||
}
|
||||
|
||||
if( NewProcessData->Console )
|
||||
{
|
||||
CLIENT_ID ClientId;
|
||||
CsrInsertObject(NewProcessData,
|
||||
&Reply->Data.CreateProcessReply.ConsoleHandle,
|
||||
&Reply->Data.CreateProcessReply.InputHandle,
|
||||
(Object_t *)NewProcessData->Console);
|
||||
RtlEnterCriticalSection( &ActiveConsoleLock );
|
||||
CsrInsertObject( NewProcessData, &Reply->Data.CreateProcessReply.OutputHandle, &(NewProcessData->Console->ActiveBuffer->Header) );
|
||||
RtlLeaveCriticalSection( &ActiveConsoleLock );
|
||||
ClientId.UniqueProcess = (HANDLE)NewProcessData->ProcessId;
|
||||
Status = NtOpenProcess( &Process, PROCESS_DUP_HANDLE, 0, &ClientId );
|
||||
if( !NT_SUCCESS( Status ) )
|
||||
{
|
||||
DbgPrint( "CSR: NtOpenProcess() failed for handle duplication\n" );
|
||||
InterlockedDecrement( &(NewProcessData->Console->Header.ReferenceCount) );
|
||||
CsrFreeProcessData( NewProcessData->ProcessId );
|
||||
Reply->Status = Status;
|
||||
return Status;
|
||||
|
@ -172,15 +174,14 @@ NTSTATUS CsrCreateProcess (PCSRSS_PROCESS_DATA ProcessData,
|
|||
{
|
||||
DbgPrint( "CSR: NtDuplicateObject() failed: %x\n", Status );
|
||||
NtClose( Process );
|
||||
InterlockedDecrement( &(NewProcessData->Console->Header.ReferenceCount) );
|
||||
CsrFreeProcessData( NewProcessData->ProcessId );
|
||||
Reply->Status = Status;
|
||||
return Status;
|
||||
}
|
||||
NtClose( Process );
|
||||
}
|
||||
else Reply->Data.CreateProcessReply.ConsoleHandle = INVALID_HANDLE_VALUE;
|
||||
// DisplayString(L"CSR: Did CreateProcess successfully\n");
|
||||
// DbgPrint("Reply->Header.MessageSize %d\n", Reply->Header.MessageSize);
|
||||
else Reply->Data.CreateProcessReply.OutputHandle = Reply->Data.CreateProcessReply.InputHandle = INVALID_HANDLE_VALUE;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: wapi.c,v 1.10 2001/01/18 15:00:09 dwelch Exp $
|
||||
/* $Id: wapi.c,v 1.11 2001/01/21 00:11:54 phreak Exp $
|
||||
*
|
||||
* reactos/subsys/csrss/api/wapi.c
|
||||
*
|
||||
|
@ -44,6 +44,8 @@ static const CsrFunc CsrFuncs[] = {
|
|||
CsrSetTextAttrib,
|
||||
CsrGetConsoleMode,
|
||||
CsrSetConsoleMode,
|
||||
CsrCreateScreenBuffer,
|
||||
CsrSetScreenBuffer,
|
||||
0 };
|
||||
|
||||
static void Thread_Api2(HANDLE ServerPort)
|
||||
|
|
Loading…
Reference in a new issue