From 30f0e5cc98df5ce22e02fe1ce2db1aeb50029021 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 26 Aug 2013 07:16:10 +0000 Subject: [PATCH] [SACDRV]: Switch !SAC back to VT-UTF8 and remove the previous hacks. [SACDRV]: We need VTUTF8ChannelOEcho. Implement VTUTF8ChannelAnsiDispatch in anticipation. svn path=/trunk/; revision=59829 --- reactos/drivers/sac/driver/conmgr.c | 6 +- reactos/drivers/sac/driver/sacdrv.h | 22 +++- reactos/drivers/sac/driver/vtutf8chan.c | 130 ++++++++++++++++++++++-- 3 files changed, 147 insertions(+), 11 deletions(-) diff --git a/reactos/drivers/sac/driver/conmgr.c b/reactos/drivers/sac/driver/conmgr.c index fda85472bc5..b69d8ad838f 100644 --- a/reactos/drivers/sac/driver/conmgr.c +++ b/reactos/drivers/sac/driver/conmgr.c @@ -169,7 +169,7 @@ ConMgrInitialize(VOID) /* Setup the attributes for the raw SAC channel */ RtlZeroMemory(&SacChannelAttributes, sizeof(SacChannelAttributes)); - SacChannelAttributes.ChannelType = Raw; /* FIXME: Should be VtUtf8 */ + SacChannelAttributes.ChannelType = VtUtf8; /* Get the right name for it */ pcwch = GetMessage(SAC_CHANNEL_NAME); @@ -725,7 +725,7 @@ DoLineParsing: /* Read every character in the channel, and strip whitespace */ ChannelIRead(CurrentChannel, ReadBuffer, - sizeof(CHAR), /* FIXME: Should be sizeof(ReadBuffer) */ + sizeof(ReadBuffer), &ReadBufferSize); } while ((ReadBufferSize) && ((ReadBuffer[0] == ' ') || (ReadBuffer[0] == '\t'))); @@ -740,7 +740,7 @@ DoLineParsing: /* Read each character -- there should be max 80 */ ChannelIRead(CurrentChannel, ReadBuffer, - sizeof(CHAR), /* FIXME: Should be sizeof(ReadBuffer) */ + sizeof(ReadBuffer), &ReadBufferSize); ASSERT(i < SAC_VTUTF8_COL_WIDTH); InputBuffer[i++] = ReadBuffer[0]; diff --git a/reactos/drivers/sac/driver/sacdrv.h b/reactos/drivers/sac/driver/sacdrv.h index 2490cf1b173..8ea85eed158 100644 --- a/reactos/drivers/sac/driver/sacdrv.h +++ b/reactos/drivers/sac/driver/sacdrv.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -211,7 +212,7 @@ typedef struct _SAC_MESSAGE_ENTRY } SAC_MESSAGE_ENTRY, *PSAC_MESSAGE_ENTRY; // -// These are the VT-100/220/ANSI Escape Codes supported by SAC +// These are the VT-100/220/ANSI Escape Codes supported by SAC as input // typedef enum _SAC_ANSI_COMMANDS { @@ -241,6 +242,25 @@ typedef enum _SAC_ANSI_COMMANDS SacSetColorsAndAttributes } SAC_ANSI_COMMANDS; +// +// These are the VT-100/220/ANSI Escape Codes send by SAC as output +// +typedef enum _SAC_ANSI_DISPATCH +{ + SacAnsiClearScreen, + SacAnsiClearEndOfScreen, + SacAnsiClearEndOfLine, + SacAnsiSetColors, + SacAnsiSetPosition, + SacAnsiClearAttributes, + SacAnsiSetInverseAttribute, + SacAnsiClearInverseAttribute, + SacAnsiSetBlinkAttribute, + SacAnsiClearBlinkAttribute, + SacAnsiSetBoldAttribute, + SacAnsiClearBoldAttribute +} SAC_ANSI_DISPATCH; + // // SAC supports 3 different channel output types // diff --git a/reactos/drivers/sac/driver/vtutf8chan.c b/reactos/drivers/sac/driver/vtutf8chan.c index 3ba7a1072e1..90356326cc7 100644 --- a/reactos/drivers/sac/driver/vtutf8chan.c +++ b/reactos/drivers/sac/driver/vtutf8chan.c @@ -65,14 +65,130 @@ VTUTF8ChannelScanForNumber(IN PWCHAR String, NTSTATUS NTAPI -VTUTF8ChannelAnsiDispatch( - IN NTSTATUS Status, - IN ULONG AnsiCode, - IN PWCHAR Data, - IN ULONG Length - ) +VTUTF8ChannelAnsiDispatch(IN PSAC_CHANNEL Channel, + IN SAC_ANSI_DISPATCH AnsiCode, + IN INT* Data, + IN ULONG Length) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status = STATUS_SUCCESS; + PCHAR LocalBuffer = NULL; + INT l; + CHECK_PARAMETER1(Channel); + + /* Check which ANSI sequence we should output */ + switch (AnsiCode) + { + /* Send the [2J (Clear Screen and Reset Cursor) */ + case SacAnsiClearScreen: + LocalBuffer = "\x1B[2J"; + break; + + /* Send the [0J (Clear From Position Till End Of Screen) */ + case SacAnsiClearEndOfScreen: + LocalBuffer = "\x1B[0J"; + break; + + /* Send the [0K (Clear from Position Till End Of Line) */ + case SacAnsiClearEndOfLine: + LocalBuffer = "\x1B[0K"; + break; + + /* Send a combination of two [#m attribute changes */ + case SacAnsiSetColors: + + /* Allocate a small local buffer for it */ + LocalBuffer = SacAllocatePool(SAC_VTUTF8_COL_WIDTH, GLOBAL_BLOCK_TAG); + CHECK_ALLOCATION(LocalBuffer); + + /* Caller should have sent two colors as two integers */ + if (!(Data) || (Length != 8)) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + /* Create the escape sequence string */ + l = sprintf(LocalBuffer, "\x1B[%dm\x1B[%dm", Data[1], Data[0]); + ASSERT((l + 1)*sizeof(UCHAR) < SAC_VTUTF8_COL_WIDTH); + ASSERT(LocalBuffer); + break; + + /* Send the [#;#H (Cursor Positio) sequence */ + case SacAnsiSetPosition: + + /* Allocate a small local buffer for it */ + LocalBuffer = SacAllocatePool(SAC_VTUTF8_COL_WIDTH, GLOBAL_BLOCK_TAG); + CHECK_ALLOCATION(LocalBuffer); + + /* Caller should have sent the position as two integers */ + if (!(Data) || (Length != 8)) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + /* Create the escape sequence string */ + l = sprintf(LocalBuffer, "\x1B[%d;%dH", Data[1] + 1, Data[0] + 1); + ASSERT((l + 1)*sizeof(UCHAR) < SAC_VTUTF8_COL_WIDTH); + ASSERT(LocalBuffer); + break; + + /* Send the [0m sequence (Set Attribute 0) */ + case SacAnsiClearAttributes: + LocalBuffer = "\x1B[0m"; + break; + + /* Send the [7m sequence (Set Attribute 7) */ + case SacAnsiSetInverseAttribute: + LocalBuffer = "\x1B[7m"; + break; + + /* Send the [27m sequence (Set Attribute 27) */ + case SacAnsiClearInverseAttribute: + LocalBuffer = "\x1B[27m"; + break; + + /* Send the [5m sequence (Set Attribute 5) */ + case SacAnsiSetBlinkAttribute: + LocalBuffer = "\x1B[5m"; + break; + + /* Send the [25m sequence (Set Attribute 25) */ + case SacAnsiClearBlinkAttribute: + LocalBuffer = "\x1B[25m"; + break; + + /* Send the [1m sequence (Set Attribute 1) */ + case SacAnsiSetBoldAttribute: + LocalBuffer = "\x1B[1m"; + break; + + /* Send the [22m sequence (Set Attribute 22) */ + case SacAnsiClearBoldAttribute: + LocalBuffer = "\x1B[22m"; + break; + + /* We don't recognize it */ + default: + Status = STATUS_INVALID_PARAMETER; + break; + } + + /* Did everything work above? */ + if (NT_SUCCESS(Status)) + { + /* Go write out the sequence */ + Status = ConMgrWriteData(Channel, LocalBuffer, strlen(LocalBuffer)); + if (NT_SUCCESS(Status)) + { + /* Now flush it */ + Status = ConMgrFlushData(Channel); + } + } + + /* Free the temporary buffer, if any, and return the status */ + if (LocalBuffer) SacFreePool(LocalBuffer); + return Status; } NTSTATUS