Author: ion Date: Mon Aug 26 08:12:52 2013 New Revision: 59830
URL: http://svn.reactos.org/svn/reactos?rev=59830&view=rev Log: [SACDRV]: Implement VTUTF8ChannelProcessAttributes and VTUTF8ChannelOFlush, since these are also needed for output. Time to test for real now.
Modified: trunk/reactos/drivers/sac/driver/vtutf8chan.c
Modified: trunk/reactos/drivers/sac/driver/vtutf8chan.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/sac/driver/vtutf8ch... ============================================================================== --- trunk/reactos/drivers/sac/driver/vtutf8chan.c [iso-8859-1] (original) +++ trunk/reactos/drivers/sac/driver/vtutf8chan.c [iso-8859-1] Mon Aug 26 08:12:52 2013 @@ -193,12 +193,37 @@
NTSTATUS NTAPI -VTUTF8ChannelProcessAttributes( - IN PSAC_CHANNEL Channel, - IN UCHAR Attribute - ) -{ - return STATUS_NOT_IMPLEMENTED; +VTUTF8ChannelProcessAttributes(IN PSAC_CHANNEL Channel, + IN UCHAR Attribute) +{ + NTSTATUS Status; + CHECK_PARAMETER(Channel); + + /* Set bold if needed */ + Status = VTUTF8ChannelAnsiDispatch(Channel, + Attribute & SAC_CURSOR_FLAG_BOLD ? + SacAnsiSetBoldAttribute : + SacAnsiClearBoldAttribute, + NULL, + 0); + if (!NT_SUCCESS(Status)) return Status; + + /* Set blink if needed */ + Status = VTUTF8ChannelAnsiDispatch(Channel, + Attribute & SAC_CURSOR_FLAG_BLINK ? + SacAnsiSetBlinkAttribute : + SacAnsiClearBlinkAttribute, + NULL, + 0); + if (!NT_SUCCESS(Status)) return Status; + + /* Set inverse if needed */ + return VTUTF8ChannelAnsiDispatch(Channel, + Attribute & SAC_CURSOR_FLAG_INVERTED ? + SacAnsiSetInverseAttribute : + SacAnsiClearInverseAttribute, + NULL, + 0); }
// @@ -712,8 +737,211 @@ NTAPI VTUTF8ChannelOFlush(IN PSAC_CHANNEL Channel) { - ASSERT(FALSE); - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + PSAC_CURSOR_DATA Cursor; + INT Color[2], Position[2]; + ULONG Utf8ProcessedCount, Utf8Count, R, C, ForeColor, BackColor, Attribute; + PWCHAR TmpBuffer; + BOOLEAN Overflow = FALSE; + CHECK_PARAMETER(Channel); + + /* Set the cell buffer position */ + Cursor = (PSAC_CURSOR_DATA)Channel->OBuffer; + + /* Allocate a temporary buffer */ + TmpBuffer = SacAllocatePool(40, GLOBAL_BLOCK_TAG); + if (!TmpBuffer) + { + Status = STATUS_NO_MEMORY; + goto Quickie; + } + + /* First, clear the screen */ + Status = VTUTF8ChannelAnsiDispatch(Channel, + SacAnsiClearScreen, + NULL, + 0); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Next, reset the cursor position */ + Position[1] = 0; + Position[0] = 0; + Status = VTUTF8ChannelAnsiDispatch(Channel, + SacAnsiSetPosition, + Position, + sizeof(Position)); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Finally, reset the attributes */ + Status = VTUTF8ChannelAnsiDispatch(Channel, + SacAnsiClearAttributes, + NULL, + 0); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Now set the current cursor attributes */ + Attribute = Channel->CursorFlags; + Status = VTUTF8ChannelProcessAttributes(Channel, Attribute); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* And set the current cursor colors */ + ForeColor = Channel->CursorColor; + BackColor = Channel->CursorBackColor; + Color[1] = BackColor; + Color[0] = ForeColor; + Status = VTUTF8ChannelAnsiDispatch(Channel, + SacAnsiSetColors, + Color, + sizeof(Color)); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Now loop all the characters in the cell buffer */ + for (R = 0; R < SAC_VTUTF8_ROW_HEIGHT; R++) + { + /* Accross every row */ + for (C = 0; C < SAC_VTUTF8_COL_WIDTH; C++) + { + /* Check if there's been a change in colors */ + if ((Cursor[(R * SAC_VTUTF8_COL_WIDTH) + + (C * SAC_VTUTF8_ROW_HEIGHT)].CursorBackColor != BackColor) || + (Cursor[(R * SAC_VTUTF8_COL_WIDTH) + + (C * SAC_VTUTF8_ROW_HEIGHT)].CursorColor != ForeColor)) + { + /* New colors are being drawn -- are we also on a new row now? */ + if (Overflow) + { + /* Reposition the cursor correctly */ + Position[1] = R; + Position[0] = C; + Status = VTUTF8ChannelAnsiDispatch(Channel, + SacAnsiSetPosition, + Position, + sizeof(Position)); + if (!NT_SUCCESS(Status)) goto Quickie; + Overflow = FALSE; + } + + /* Cache the new colors */ + ForeColor = Cursor[(R * SAC_VTUTF8_COL_WIDTH) + + (C * SAC_VTUTF8_ROW_HEIGHT)].CursorColor; + BackColor = Cursor[(R * SAC_VTUTF8_COL_WIDTH) + + (C * SAC_VTUTF8_ROW_HEIGHT)].CursorBackColor; + + /* Set them on the screen */ + Color[1] = BackColor; + Color[0] = ForeColor; + Status = VTUTF8ChannelAnsiDispatch(Channel, + SacAnsiSetColors, + Color, + sizeof(Color)); + if (!NT_SUCCESS(Status)) goto Quickie; + } + + /* Check if there's been a chance in attributes */ + if (Cursor->CursorFlags != Attribute) + { + /* Yep! Are we also on a new row now? */ + if (Overflow) + { + /* Reposition the cursor correctly */ + Position[1] = R; + Position[0] = C; + Status = VTUTF8ChannelAnsiDispatch(Channel, + SacAnsiSetPosition, + Position, + sizeof(Position)); + if (!NT_SUCCESS(Status)) goto Quickie; + Overflow = FALSE; + } + + /* Set the new attributes on screen */ + Attribute = Cursor->CursorFlags; + Status = VTUTF8ChannelProcessAttributes(Channel, Attribute); + if (!NT_SUCCESS(Status)) goto Quickie; + } + + /* Time to write the character -- are we on a new row now? */ + if (Overflow) + { + /* Reposition the cursor correctly */ + Position[1] = R; + Position[0] = C; + Status = VTUTF8ChannelAnsiDispatch(Channel, + SacAnsiSetPosition, + Position, + sizeof(Position)); + if (!NT_SUCCESS(Status)) goto Quickie; + Overflow = FALSE; + } + + /* Write the character into our temporary buffer */ + *TmpBuffer = Cursor[(R * SAC_VTUTF8_COL_WIDTH) + + (C * SAC_VTUTF8_ROW_HEIGHT)].CursorValue; + TmpBuffer[1] = UNICODE_NULL; + + /* Convert it to UTF-8 */ + if (!SacTranslateUnicodeToUtf8(TmpBuffer, + 1, + Utf8ConversionBuffer, + Utf8ConversionBufferSize, + &Utf8Count, + &Utf8ProcessedCount)) + { + /* Bail out if this failed */ + Status = STATUS_UNSUCCESSFUL; + goto Quickie; + } + + /* Make sure we have a remaining valid character */ + if (Utf8Count) + { + /* Write it out on the wire */ + Status = ConMgrWriteData(Channel, Utf8ConversionBuffer, Utf8Count); + if (!NT_SUCCESS(Status)) goto Quickie; + } + } + + /* All the characters on the row are done, indicate we need a reset */ + Overflow = TRUE; + } + + /* Everything is done, set the positition one last time */ + Position[1] = Channel->CursorRow; + Position[0] = Channel->CursorCol; + Status = VTUTF8ChannelAnsiDispatch(Channel, + SacAnsiSetPosition, + Position, + sizeof(Position)); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Set the current attribute one last time */ + Status = VTUTF8ChannelProcessAttributes(Channel, Channel->CursorFlags); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Set the current colors one last time */ + Color[1] = Channel->CursorBackColor; + Color[0] = Channel->CursorColor; + Status = VTUTF8ChannelAnsiDispatch(Channel, + SacAnsiSetColors, + Color, + sizeof(Color)); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Flush all the data out on the wire */ + Status = ConMgrFlushData(Channel); + +Quickie: + /* We're done, free the temporary buffer */ + if (TmpBuffer) SacFreePool(TmpBuffer); + + /* Indicate that all new data has been flushed now */ + if (NT_SUCCESS(Status)) + { + _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 0); + } + + /* Return the result */ + return Status; }
NTSTATUS