Author: jmorlan
Date: Fri Jun 27 07:34:08 2008
New Revision: 34129
URL:
http://svn.reactos.org/svn/reactos?rev=34129&view=rev
Log:
Miscellaneous console bugfixes. See Bug 3267 for details.
Modified:
trunk/reactos/dll/win32/kernel32/misc/console.c
trunk/reactos/subsystems/win32/csrss/win32csr/conio.c
Modified: trunk/reactos/dll/win32/kernel32/misc/console.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/co…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/misc/console.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/misc/console.c [iso-8859-1] Fri Jun 27 07:34:08 2008
@@ -1646,6 +1646,7 @@
return FALSE;
}
+ NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
return TRUE;
}
@@ -3215,6 +3216,7 @@
}
}
}
+ SetLastError(ERROR_INVALID_PARAMETER);
return(FALSE);
}
@@ -3843,6 +3845,7 @@
{
/* buffer is not large enough, return the required size */
RtlLeaveCriticalSection(&ConsoleLock);
+ SetLastError(ERROR_BUFFER_OVERFLOW);
return lenName + 1;
}
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/conio.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/conio.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/conio.c [iso-8859-1] Fri Jun 27 07:34:08
2008
@@ -27,11 +27,14 @@
#define ConioIsRectEmpty(Rect) \
(((Rect)->left > (Rect)->right) || ((Rect)->top > (Rect)->bottom))
+#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
+ WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
+
#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
- WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
+ WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL,
NULL)
#define ConsoleAnsiCharToUnicodeChar(Console, sWChar, dChar) \
- MultiByteToWideChar((Console)->CodePage, 0, (dChar), 1, (sWChar), 1)
+ MultiByteToWideChar((Console)->OutputCodePage, 0, (dChar), 1, (sWChar), 1)
/* FUNCTIONS *****************************************************************/
@@ -398,20 +401,20 @@
static VOID FASTCALL
ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines)
{
- /* slide the viewable screen */
- if (((Buff->CurrentY - Buff->ShowY + Buff->MaxY) % Buff->MaxY) ==
(ULONG)Buff->MaxY - 1)
+ if (++Buff->CurrentY == Buff->MaxY)
+ {
+ Buff->CurrentY = 0;
+ }
+ /* If we hit bottom, slide the viewable screen */
+ if (Buff->CurrentY == Buff->ShowY)
{
if (++Buff->ShowY == Buff->MaxY)
{
Buff->ShowY = 0;
}
(*ScrolledLines)++;
- }
- if (++Buff->CurrentY == Buff->MaxY)
- {
- Buff->CurrentY = 0;
- }
- ClearLineBuffer(Buff);
+ ClearLineBuffer(Buff);
+ }
UpdateRect->left = 0;
UpdateRect->right = Buff->MaxX - 1;
if (UpdateRect->top == (LONG)Buff->CurrentY)
@@ -510,6 +513,7 @@
while (Buff->CurrentX < EndX)
{
Buff->Buffer[Offset] = ' ';
+ Buff->Buffer[Offset + 1] = Buff->DefaultAttrib;
Offset += 2;
Buff->CurrentX++;
}
@@ -726,14 +730,6 @@
}
}
-BOOLEAN __inline ConioIsEqualRect(
- RECT *Rect1,
- RECT *Rect2)
-{
- return ((Rect1->left == Rect2->left) && (Rect1->right ==
Rect2->right) &&
- (Rect1->top == Rect2->top) && (Rect1->bottom == Rect2->bottom));
-}
-
BOOLEAN __inline ConioGetIntersection(
RECT *Intersection,
RECT *Rect1,
@@ -793,138 +789,65 @@
return TRUE;
}
-BOOLEAN __inline ConioSubtractRect(
- RECT *Subtraction,
- RECT *Rect1,
- RECT *Rect2)
-{
- RECT tmp;
-
- if (ConioIsRectEmpty(Rect1))
- {
- ConioInitRect(Subtraction, 0, -1, 0, -1);
- return FALSE;
- }
- *Subtraction = *Rect1;
- if (ConioGetIntersection(&tmp, Rect1, Rect2))
- {
- if (ConioIsEqualRect(&tmp, Subtraction))
- {
- ConioInitRect(Subtraction, 0, -1, 0, -1);
- return FALSE;
- }
- if ((tmp.top == Subtraction->top) && (tmp.bottom ==
Subtraction->bottom))
- {
- if (tmp.left == Subtraction->left)
- {
- Subtraction->left = tmp.right;
- }
- else if (tmp.right == Subtraction->right)
- {
- Subtraction->right = tmp.left;
- }
- }
- else if ((tmp.left == Subtraction->left) && (tmp.right ==
Subtraction->right))
- {
- if (tmp.top == Subtraction->top)
- {
- Subtraction->top = tmp.bottom;
- }
- else if (tmp.bottom == Subtraction->bottom)
- {
- Subtraction->bottom = tmp.top;
- }
- }
- }
-
- return TRUE;
-}
-
+/* Move from one rectangle to another. We must be careful about the order that
+ * this is done, to avoid overwriting parts of the source before they are moved. */
static VOID FASTCALL
-ConioCopyRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
+ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
RECT *SrcRegion,
- RECT *DstRegion)
-{
- SHORT SrcY, DstY;
- DWORD SrcOffset;
- DWORD DstOffset;
- DWORD BytesPerLine;
- LONG i;
-
- DstY = DstRegion->top;
- BytesPerLine = ConioRectWidth(DstRegion) * 2;
-
- SrcY = (SrcRegion->top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
- DstY = (DstRegion->top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
- SrcOffset = (SrcY * ScreenBuffer->MaxX + SrcRegion->left +
ScreenBuffer->ShowX) * 2;
- DstOffset = (DstY * ScreenBuffer->MaxX + DstRegion->left +
ScreenBuffer->ShowX) * 2;
-
- for (i = SrcRegion->top; i <= SrcRegion->bottom; i++)
- {
- RtlCopyMemory(
- &ScreenBuffer->Buffer[DstOffset],
- &ScreenBuffer->Buffer[SrcOffset],
- BytesPerLine);
-
- if (++DstY == ScreenBuffer->MaxY)
- {
- DstY = 0;
- DstOffset = (DstRegion->left + ScreenBuffer->ShowX) * 2;
- }
- else
- {
- DstOffset += ScreenBuffer->MaxX * 2;
- }
-
- if (++SrcY == ScreenBuffer->MaxY)
- {
- SrcY = 0;
- SrcOffset = (SrcRegion->left + ScreenBuffer->ShowX) * 2;
- }
- else
- {
- SrcOffset += ScreenBuffer->MaxX * 2;
- }
- }
-}
-
-static VOID FASTCALL
-ConioFillRegion(PCSRSS_CONSOLE Console,
- PCSRSS_SCREEN_BUFFER ScreenBuffer,
- RECT *Region,
- CHAR_INFO *CharInfo,
- BOOL bUnicode)
-{
- SHORT X, Y;
- DWORD Offset;
- DWORD Delta;
- LONG i;
- CHAR Char;
-
- if(bUnicode)
- ConsoleUnicodeCharToAnsiChar(Console, &Char,
&CharInfo->Char.UnicodeChar);
- else
- Char = CharInfo->Char.AsciiChar;
-
- Y = (Region->top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
- Offset = (Y * ScreenBuffer->MaxX + Region->left + ScreenBuffer->ShowX) * 2;
- Delta = (ScreenBuffer->MaxX - ConioRectWidth(Region)) * 2;
-
- for (i = Region->top; i <= Region->bottom; i++)
- {
- for (X = Region->left; X <= Region->right; X++)
- {
- SET_CELL_BUFFER(ScreenBuffer, Offset, Char, CharInfo->Attributes);
- }
- if (++Y == ScreenBuffer->MaxY)
- {
- Y = 0;
- Offset = (Region->left + ScreenBuffer->ShowX) * 2;
- }
- else
- {
- Offset += Delta;
- }
+ RECT *DstRegion,
+ RECT *ClipRegion,
+ WORD Fill)
+{
+ int Width = ConioRectWidth(SrcRegion);
+ int Height = ConioRectHeight(SrcRegion);
+ int SX, SY;
+ int DX, DY;
+ int XDelta, YDelta;
+ int i, j;
+
+ SY = SrcRegion->top;
+ DY = DstRegion->top;
+ YDelta = 1;
+ if (SY < DY)
+ {
+ /* Moving down: work from bottom up */
+ SY = SrcRegion->bottom;
+ DY = DstRegion->bottom;
+ YDelta = -1;
+ }
+ for (i = 0; i < Height; i++)
+ {
+ PWORD SRow = (PWORD)&ScreenBuffer->Buffer[((SY + ScreenBuffer->ShowY) %
ScreenBuffer->MaxY) * ScreenBuffer->MaxX * 2];
+ PWORD DRow = (PWORD)&ScreenBuffer->Buffer[((DY + ScreenBuffer->ShowY) %
ScreenBuffer->MaxY) * ScreenBuffer->MaxX * 2];
+
+ SX = SrcRegion->left;
+ DX = DstRegion->left;
+ XDelta = 1;
+ if (SX < DX)
+ {
+ /* Moving right: work from right to left */
+ SX = SrcRegion->right;
+ DX = DstRegion->right;
+ XDelta = -1;
+ }
+ for (j = 0; j < Width; j++)
+ {
+ WORD Cell = SRow[SX];
+ if (SX >= ClipRegion->left && SX <= ClipRegion->right
+ && SY >= ClipRegion->top && SY <=
ClipRegion->bottom)
+ {
+ SRow[SX] = Fill;
+ }
+ if (DX >= ClipRegion->left && DX <= ClipRegion->right
+ && DY >= ClipRegion->top && DY <=
ClipRegion->bottom)
+ {
+ DRow[DX] = Cell;
+ }
+ SX += XDelta;
+ DX += XDelta;
+ }
+ SY += YDelta;
+ DY += YDelta;
}
}
@@ -935,9 +858,9 @@
{
WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
- ConsoleUnicodeCharToAnsiChar(Console,
- &InputEvent->Event.KeyEvent.uChar.AsciiChar,
- &UnicodeChar);
+ ConsoleInputUnicodeCharToAnsiChar(Console,
+
&InputEvent->Event.KeyEvent.uChar.AsciiChar,
+ &UnicodeChar);
}
}
@@ -974,14 +897,14 @@
if(Request->Data.WriteConsoleRequest.Unicode)
{
- Length = WideCharToMultiByte(Console->CodePage, 0,
+ Length = WideCharToMultiByte(Console->OutputCodePage, 0,
(PWCHAR)Request->Data.WriteConsoleRequest.Buffer,
Request->Data.WriteConsoleRequest.NrCharactersToWrite,
NULL, 0, NULL, NULL);
Buffer = RtlAllocateHeap(GetProcessHeap(), 0, Length);
if (Buffer)
{
- WideCharToMultiByte(Console->CodePage, 0,
+ WideCharToMultiByte(Console->OutputCodePage, 0,
(PWCHAR)Request->Data.WriteConsoleRequest.Buffer,
Request->Data.WriteConsoleRequest.NrCharactersToWrite,
Buffer, Length, NULL, NULL);
@@ -1585,14 +1508,14 @@
{
if(Request->Data.WriteConsoleOutputCharRequest.Unicode)
{
- Length = WideCharToMultiByte(Console->CodePage, 0,
+ Length = WideCharToMultiByte(Console->OutputCodePage, 0,
(PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String,
Request->Data.WriteConsoleOutputCharRequest.Length,
NULL, 0, NULL, NULL);
tmpString = String = RtlAllocateHeap(GetProcessHeap(), 0, Length);
if (String)
{
- WideCharToMultiByte(Console->CodePage, 0,
+ WideCharToMultiByte(Console->OutputCodePage, 0,
(PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String,
Request->Data.WriteConsoleOutputCharRequest.Length,
String, Length, NULL, NULL);
@@ -2257,14 +2180,14 @@
if (! NT_SUCCESS(Status))
{
ConioUnlockConsole(Console);
- return Request->Status;
+ return Request->Status = Status;
}
if (Buff == Console->ActiveBuffer)
{
ConioUnlockScreenBuffer(Buff);
ConioUnlockConsole(Console);
- return STATUS_SUCCESS;
+ return Request->Status = STATUS_SUCCESS;
}
/* drop reference to old buffer, maybe delete */
@@ -2528,15 +2451,15 @@
RECT ScreenBuffer;
RECT SrcRegion;
RECT DstRegion;
- RECT FillRegion;
+ RECT UpdateRegion;
RECT ScrollRectangle;
RECT ClipRectangle;
NTSTATUS Status;
- BOOLEAN DoFill;
HANDLE ConsoleHandle;
BOOLEAN UseClipRectangle;
COORD DestinationOrigin;
CHAR_INFO Fill;
+ CHAR FillChar;
DPRINT("CsrScrollConsoleScreenBuffer\n");
@@ -2567,10 +2490,6 @@
ScrollRectangle.top =
Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Top;
ScrollRectangle.right =
Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Right;
ScrollRectangle.bottom =
Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Bottom;
- ClipRectangle.left =
Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Left;
- ClipRectangle.top =
Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Top;
- ClipRectangle.right =
Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Right;
- ClipRectangle.bottom =
Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Bottom;
/* Make sure source rectangle is inside the screen buffer */
ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
@@ -2581,63 +2500,60 @@
{
ConioUnlockConsole(Console);
}
- return Request->Status = STATUS_INVALID_PARAMETER;
- }
-
- if (UseClipRectangle && ! ConioGetIntersection(&SrcRegion, &SrcRegion,
&ClipRectangle))
- {
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
- ConioUnlockScreenBuffer(Buff);
return Request->Status = STATUS_SUCCESS;
}
+ /* If the source was clipped on the left or top, adjust the destination accordingly */
+ if (ScrollRectangle.left < 0)
+ {
+ DestinationOrigin.X -= ScrollRectangle.left;
+ }
+ if (ScrollRectangle.top < 0)
+ {
+ DestinationOrigin.Y -= ScrollRectangle.top;
+ }
+
+ if (UseClipRectangle)
+ {
+ ClipRectangle.left =
Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Left;
+ ClipRectangle.top =
Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Top;
+ ClipRectangle.right =
Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Right;
+ ClipRectangle.bottom =
Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Bottom;
+ if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle,
&ScreenBuffer))
+ {
+ if (NULL != Console)
+ {
+ ConioUnlockConsole(Console);
+ }
+ ConioUnlockScreenBuffer(Buff);
+ return Request->Status = STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ ClipRectangle = ScreenBuffer;
+ }
ConioInitRect(&DstRegion,
DestinationOrigin.Y,
DestinationOrigin.X,
- DestinationOrigin.Y + ConioRectHeight(&ScrollRectangle) - 1,
- DestinationOrigin.X + ConioRectWidth(&ScrollRectangle) - 1);
-
- /* Make sure destination rectangle is inside the screen buffer */
- if (! ConioGetIntersection(&DstRegion, &DstRegion, &ScreenBuffer))
- {
- if (NULL != Console)
- {
- ConioUnlockConsole(Console);
- }
- ConioUnlockScreenBuffer(Buff);
- return Request->Status = STATUS_INVALID_PARAMETER;
- }
-
- ConioCopyRegion(Buff, &SrcRegion, &DstRegion);
-
- /* Get the region that should be filled with the specified character and attributes */
-
- DoFill = FALSE;
-
- ConioGetUnion(&FillRegion, &SrcRegion, &DstRegion);
-
- if (ConioSubtractRect(&FillRegion, &FillRegion, &DstRegion))
- {
- /* FIXME: The subtracted rectangle is off by one line */
- FillRegion.top += 1;
-
- ConioFillRegion(Console, Buff, &FillRegion, &Fill,
Request->Data.ScrollConsoleScreenBufferRequest.Unicode);
- DoFill = TRUE;
- }
+ DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1,
+ DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1);
+
+ if (Request->Data.ScrollConsoleScreenBufferRequest.Unicode)
+ ConsoleUnicodeCharToAnsiChar(Console, &FillChar, &Fill.Char.UnicodeChar);
+ else
+ FillChar = Fill.Char.AsciiChar;
+
+ ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle,
Fill.Attributes << 8 | (BYTE)FillChar);
if (NULL != Console && Buff == Console->ActiveBuffer)
{
- /* Draw destination region */
- ConioDrawRegion(Console, &DstRegion);
-
- if (DoFill)
- {
- /* Draw filled region */
- ConioDrawRegion(Console, &FillRegion);
+ ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion);
+ if (ConioGetIntersection(&UpdateRegion, &UpdateRegion,
&ClipRectangle))
+ {
+ /* Draw update region */
+ ConioDrawRegion(Console, &UpdateRegion);
}
}