mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 02:34:53 +00:00
[WIN32CSR]
- Make consistent use of RECT/SMALL_RECT structures: a RECT uses pixel coordinates relative to the window client area and is endpoint-exclusive; a SMALL_RECT uses character coordinates relative to the screen buffer and is endpoint-inclusive. - Allow text selections outside of the visible window - Implement GetConsoleSelectionInfo svn path=/trunk/; revision=47335
This commit is contained in:
parent
8f6739ed2e
commit
7fa77031b0
|
@ -3805,15 +3805,23 @@ GetConsoleProcessList(LPDWORD lpdwProcessList,
|
|||
/*--------------------------------------------------------------
|
||||
* GetConsoleSelectionInfo
|
||||
*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
|
||||
{
|
||||
DPRINT1("GetConsoleSelectionInfo(0x%x) UNIMPLEMENTED!\n", lpConsoleSelectionInfo);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
CSR_API_MESSAGE Request;
|
||||
ULONG CsrRequest = MAKE_CSR_API(GET_CONSOLE_SELECTION_INFO, CSR_CONSOLE);
|
||||
NTSTATUS Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
|
||||
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
|
||||
{
|
||||
SetLastErrorByStatus(Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*lpConsoleSelectionInfo = Request.Data.GetConsoleSelectionInfo.Info;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -473,6 +473,11 @@ typedef struct
|
|||
COORD Size;
|
||||
} CSRSS_SET_SCREEN_BUFFER_SIZE, *PCSRSS_SET_SCREEN_BUFFER_SIZE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CONSOLE_SELECTION_INFO Info;
|
||||
} CSRSS_GET_CONSOLE_SELECTION_INFO, *PCSRSS_GET_CONSOLE_SELECTION_INFO;
|
||||
|
||||
|
||||
#define CSR_API_MESSAGE_HEADER_SIZE(Type) (FIELD_OFFSET(CSR_API_MESSAGE, Data) + sizeof(Type))
|
||||
#define CSRSS_MAX_WRITE_CONSOLE (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE))
|
||||
|
@ -552,6 +557,7 @@ typedef struct
|
|||
#define GENERATE_CTRL_EVENT (0x3E)
|
||||
#define CREATE_THREAD (0x3F)
|
||||
#define SET_SCREEN_BUFFER_SIZE (0x40)
|
||||
#define GET_CONSOLE_SELECTION_INFO (0x41)
|
||||
|
||||
/* Keep in sync with definition below. */
|
||||
#define CSRSS_HEADER_SIZE (sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS))
|
||||
|
@ -626,6 +632,7 @@ typedef struct _CSR_API_MESSAGE
|
|||
CSRSS_GET_CONSOLE_ALIASES_EXES_LENGTH GetConsoleAliasesExesLength;
|
||||
CSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent;
|
||||
CSRSS_SET_SCREEN_BUFFER_SIZE SetScreenBufferSize;
|
||||
CSRSS_GET_CONSOLE_SELECTION_INFO GetConsoleSelectionInfo;
|
||||
} Data;
|
||||
} CSR_API_MESSAGE, *PCSR_API_MESSAGE;
|
||||
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
#define ConioInitRect(Rect, Top, Left, Bottom, Right) \
|
||||
((Rect)->top) = Top; \
|
||||
((Rect)->left) = Left; \
|
||||
((Rect)->bottom) = Bottom; \
|
||||
((Rect)->right) = Right
|
||||
#define ConioInitRect(Rect, top, left, bottom, right) \
|
||||
((Rect)->Top) = top; \
|
||||
((Rect)->Left) = left; \
|
||||
((Rect)->Bottom) = bottom; \
|
||||
((Rect)->Right) = right
|
||||
|
||||
#define ConioIsRectEmpty(Rect) \
|
||||
(((Rect)->left > (Rect)->right) || ((Rect)->top > (Rect)->bottom))
|
||||
(((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom))
|
||||
|
||||
#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
|
||||
WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
|
||||
|
@ -392,7 +392,7 @@ CSR_API(CsrFreeConsole)
|
|||
}
|
||||
|
||||
static VOID FASTCALL
|
||||
ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines)
|
||||
ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, UINT *ScrolledLines)
|
||||
{
|
||||
/* If we hit bottom, slide the viewable screen */
|
||||
if (++Buff->CurrentY == Buff->MaxY)
|
||||
|
@ -404,14 +404,14 @@ ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines)
|
|||
}
|
||||
(*ScrolledLines)++;
|
||||
ClearLineBuffer(Buff);
|
||||
if (UpdateRect->top != 0)
|
||||
if (UpdateRect->Top != 0)
|
||||
{
|
||||
UpdateRect->top--;
|
||||
UpdateRect->Top--;
|
||||
}
|
||||
}
|
||||
UpdateRect->left = 0;
|
||||
UpdateRect->right = Buff->MaxX - 1;
|
||||
UpdateRect->bottom = Buff->CurrentY;
|
||||
UpdateRect->Left = 0;
|
||||
UpdateRect->Right = Buff->MaxX - 1;
|
||||
UpdateRect->Bottom = Buff->CurrentY;
|
||||
}
|
||||
|
||||
static NTSTATUS FASTCALL
|
||||
|
@ -420,16 +420,16 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
|
|||
{
|
||||
UINT i;
|
||||
PBYTE Ptr;
|
||||
RECT UpdateRect;
|
||||
SMALL_RECT UpdateRect;
|
||||
LONG CursorStartX, CursorStartY;
|
||||
UINT ScrolledLines;
|
||||
|
||||
CursorStartX = Buff->CurrentX;
|
||||
CursorStartY = Buff->CurrentY;
|
||||
UpdateRect.left = Buff->MaxX;
|
||||
UpdateRect.top = Buff->CurrentY;
|
||||
UpdateRect.right = -1;
|
||||
UpdateRect.bottom = Buff->CurrentY;
|
||||
UpdateRect.Left = Buff->MaxX;
|
||||
UpdateRect.Top = Buff->CurrentY;
|
||||
UpdateRect.Right = -1;
|
||||
UpdateRect.Bottom = Buff->CurrentY;
|
||||
ScrolledLines = 0;
|
||||
|
||||
for (i = 0; i < Length; i++)
|
||||
|
@ -454,7 +454,7 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
|
|||
/* slide virtual position up */
|
||||
Buff->CurrentX = Buff->MaxX - 1;
|
||||
Buff->CurrentY--;
|
||||
UpdateRect.top = min(UpdateRect.top, (LONG)Buff->CurrentY);
|
||||
UpdateRect.Top = min(UpdateRect.Top, (LONG)Buff->CurrentY);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -463,8 +463,8 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
|
|||
Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY);
|
||||
Ptr[0] = ' ';
|
||||
Ptr[1] = Buff->DefaultAttrib;
|
||||
UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX);
|
||||
UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
|
||||
UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX);
|
||||
UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -472,8 +472,8 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
|
|||
else if (Buffer[i] == '\r')
|
||||
{
|
||||
Buff->CurrentX = 0;
|
||||
UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX);
|
||||
UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
|
||||
UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX);
|
||||
UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX);
|
||||
continue;
|
||||
}
|
||||
/* --- TAB --- */
|
||||
|
@ -481,7 +481,7 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
|
|||
{
|
||||
UINT EndX;
|
||||
|
||||
UpdateRect.left = min(UpdateRect.left, (LONG)Buff->CurrentX);
|
||||
UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX);
|
||||
EndX = (Buff->CurrentX + 8) & ~7;
|
||||
if (EndX > Buff->MaxX)
|
||||
{
|
||||
|
@ -494,7 +494,7 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
|
|||
*Ptr++ = Buff->DefaultAttrib;
|
||||
Buff->CurrentX++;
|
||||
}
|
||||
UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX - 1);
|
||||
UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX - 1);
|
||||
if (Buff->CurrentX == Buff->MaxX)
|
||||
{
|
||||
if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
|
||||
|
@ -510,8 +510,8 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
UpdateRect.left = min(UpdateRect.left, (LONG)Buff->CurrentX);
|
||||
UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
|
||||
UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX);
|
||||
UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX);
|
||||
Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY);
|
||||
Ptr[0] = Buffer[i];
|
||||
if (Attrib)
|
||||
|
@ -684,16 +684,16 @@ CSR_API(CsrReadConsole)
|
|||
}
|
||||
|
||||
__inline BOOLEAN ConioGetIntersection(
|
||||
RECT *Intersection,
|
||||
RECT *Rect1,
|
||||
RECT *Rect2)
|
||||
SMALL_RECT *Intersection,
|
||||
SMALL_RECT *Rect1,
|
||||
SMALL_RECT *Rect2)
|
||||
{
|
||||
if (ConioIsRectEmpty(Rect1) ||
|
||||
(ConioIsRectEmpty(Rect2)) ||
|
||||
(Rect1->top > Rect2->bottom) ||
|
||||
(Rect1->left > Rect2->right) ||
|
||||
(Rect1->bottom < Rect2->top) ||
|
||||
(Rect1->right < Rect2->left))
|
||||
(Rect1->Top > Rect2->Bottom) ||
|
||||
(Rect1->Left > Rect2->Right) ||
|
||||
(Rect1->Bottom < Rect2->Top) ||
|
||||
(Rect1->Right < Rect2->Left))
|
||||
{
|
||||
/* The rectangles do not intersect */
|
||||
ConioInitRect(Intersection, 0, -1, 0, -1);
|
||||
|
@ -701,18 +701,18 @@ __inline BOOLEAN ConioGetIntersection(
|
|||
}
|
||||
|
||||
ConioInitRect(Intersection,
|
||||
max(Rect1->top, Rect2->top),
|
||||
max(Rect1->left, Rect2->left),
|
||||
min(Rect1->bottom, Rect2->bottom),
|
||||
min(Rect1->right, Rect2->right));
|
||||
max(Rect1->Top, Rect2->Top),
|
||||
max(Rect1->Left, Rect2->Left),
|
||||
min(Rect1->Bottom, Rect2->Bottom),
|
||||
min(Rect1->Right, Rect2->Right));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
__inline BOOLEAN ConioGetUnion(
|
||||
RECT *Union,
|
||||
RECT *Rect1,
|
||||
RECT *Rect2)
|
||||
SMALL_RECT *Union,
|
||||
SMALL_RECT *Rect1,
|
||||
SMALL_RECT *Rect2)
|
||||
{
|
||||
if (ConioIsRectEmpty(Rect1))
|
||||
{
|
||||
|
@ -733,10 +733,10 @@ __inline BOOLEAN ConioGetUnion(
|
|||
else
|
||||
{
|
||||
ConioInitRect(Union,
|
||||
min(Rect1->top, Rect2->top),
|
||||
min(Rect1->left, Rect2->left),
|
||||
max(Rect1->bottom, Rect2->bottom),
|
||||
max(Rect1->right, Rect2->right));
|
||||
min(Rect1->Top, Rect2->Top),
|
||||
min(Rect1->Left, Rect2->Left),
|
||||
max(Rect1->Bottom, Rect2->Bottom),
|
||||
max(Rect1->Right, Rect2->Right));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -746,9 +746,9 @@ __inline BOOLEAN ConioGetUnion(
|
|||
* this is done, to avoid overwriting parts of the source before they are moved. */
|
||||
static VOID FASTCALL
|
||||
ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
|
||||
RECT *SrcRegion,
|
||||
RECT *DstRegion,
|
||||
RECT *ClipRegion,
|
||||
SMALL_RECT *SrcRegion,
|
||||
SMALL_RECT *DstRegion,
|
||||
SMALL_RECT *ClipRegion,
|
||||
WORD Fill)
|
||||
{
|
||||
int Width = ConioRectWidth(SrcRegion);
|
||||
|
@ -758,14 +758,14 @@ ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
|
|||
int XDelta, YDelta;
|
||||
int i, j;
|
||||
|
||||
SY = SrcRegion->top;
|
||||
DY = DstRegion->top;
|
||||
SY = SrcRegion->Top;
|
||||
DY = DstRegion->Top;
|
||||
YDelta = 1;
|
||||
if (SY < DY)
|
||||
{
|
||||
/* Moving down: work from bottom up */
|
||||
SY = SrcRegion->bottom;
|
||||
DY = DstRegion->bottom;
|
||||
SY = SrcRegion->Bottom;
|
||||
DY = DstRegion->Bottom;
|
||||
YDelta = -1;
|
||||
}
|
||||
for (i = 0; i < Height; i++)
|
||||
|
@ -773,26 +773,26 @@ ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
|
|||
PWORD SRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, SY);
|
||||
PWORD DRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, DY);
|
||||
|
||||
SX = SrcRegion->left;
|
||||
DX = DstRegion->left;
|
||||
SX = SrcRegion->Left;
|
||||
DX = DstRegion->Left;
|
||||
XDelta = 1;
|
||||
if (SX < DX)
|
||||
{
|
||||
/* Moving right: work from right to left */
|
||||
SX = SrcRegion->right;
|
||||
DX = DstRegion->right;
|
||||
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)
|
||||
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)
|
||||
if (DX >= ClipRegion->Left && DX <= ClipRegion->Right
|
||||
&& DY >= ClipRegion->Top && DY <= ClipRegion->Bottom)
|
||||
{
|
||||
DRow[DX] = Cell;
|
||||
}
|
||||
|
@ -920,7 +920,7 @@ ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer)
|
|||
VOID FASTCALL
|
||||
ConioDrawConsole(PCSRSS_CONSOLE Console)
|
||||
{
|
||||
RECT Region;
|
||||
SMALL_RECT Region;
|
||||
|
||||
ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1);
|
||||
|
||||
|
@ -1362,29 +1362,29 @@ CSR_API(CsrSetCursor)
|
|||
}
|
||||
|
||||
static VOID FASTCALL
|
||||
ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, COORD *Start, UINT Length)
|
||||
ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, COORD *Start, UINT Length)
|
||||
{
|
||||
if (Buff->MaxX <= Start->X + Length)
|
||||
{
|
||||
UpdateRect->left = 0;
|
||||
UpdateRect->Left = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateRect->left = Start->X;
|
||||
UpdateRect->Left = Start->X;
|
||||
}
|
||||
if (Buff->MaxX <= Start->X + Length)
|
||||
{
|
||||
UpdateRect->right = Buff->MaxX - 1;
|
||||
UpdateRect->Right = Buff->MaxX - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateRect->right = Start->X + Length - 1;
|
||||
UpdateRect->Right = Start->X + Length - 1;
|
||||
}
|
||||
UpdateRect->top = Start->Y;
|
||||
UpdateRect->bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX;
|
||||
if (Buff->MaxY <= UpdateRect->bottom)
|
||||
UpdateRect->Top = Start->Y;
|
||||
UpdateRect->Bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX;
|
||||
if (Buff->MaxY <= UpdateRect->Bottom)
|
||||
{
|
||||
UpdateRect->bottom = Buff->MaxY - 1;
|
||||
UpdateRect->Bottom = Buff->MaxY - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1396,7 +1396,7 @@ CSR_API(CsrWriteConsoleOutputChar)
|
|||
PCSRSS_CONSOLE Console;
|
||||
PCSRSS_SCREEN_BUFFER Buff;
|
||||
DWORD X, Y, Length, CharSize, Written = 0;
|
||||
RECT UpdateRect;
|
||||
SMALL_RECT UpdateRect;
|
||||
|
||||
DPRINT("CsrWriteConsoleOutputChar\n");
|
||||
|
||||
|
@ -1498,7 +1498,7 @@ CSR_API(CsrFillOutputChar)
|
|||
DWORD X, Y, Length, Written = 0;
|
||||
CHAR Char;
|
||||
PBYTE Buffer;
|
||||
RECT UpdateRect;
|
||||
SMALL_RECT UpdateRect;
|
||||
|
||||
DPRINT("CsrFillOutputChar\n");
|
||||
|
||||
|
@ -1636,7 +1636,7 @@ CSR_API(CsrWriteConsoleOutputAttrib)
|
|||
PWORD Attribute;
|
||||
int X, Y, Length;
|
||||
NTSTATUS Status;
|
||||
RECT UpdateRect;
|
||||
SMALL_RECT UpdateRect;
|
||||
|
||||
DPRINT("CsrWriteConsoleOutputAttrib\n");
|
||||
|
||||
|
@ -1705,7 +1705,7 @@ CSR_API(CsrFillOutputAttrib)
|
|||
NTSTATUS Status;
|
||||
int X, Y, Length;
|
||||
UCHAR Attr;
|
||||
RECT UpdateRect;
|
||||
SMALL_RECT UpdateRect;
|
||||
PCSRSS_CONSOLE Console;
|
||||
|
||||
DPRINT("CsrFillOutputAttrib\n");
|
||||
|
@ -2119,9 +2119,9 @@ CSR_API(CsrWriteConsoleOutput)
|
|||
SHORT i, X, Y, SizeX, SizeY;
|
||||
PCSRSS_CONSOLE Console;
|
||||
PCSRSS_SCREEN_BUFFER Buff;
|
||||
RECT ScreenBuffer;
|
||||
SMALL_RECT ScreenBuffer;
|
||||
CHAR_INFO* CurCharInfo;
|
||||
RECT WriteRegion;
|
||||
SMALL_RECT WriteRegion;
|
||||
CHAR_INFO* CharInfo;
|
||||
COORD BufferCoord;
|
||||
COORD BufferSize;
|
||||
|
@ -2154,15 +2154,12 @@ CSR_API(CsrWriteConsoleOutput)
|
|||
ConioUnlockScreenBuffer(Buff);
|
||||
return STATUS_ACCESS_VIOLATION;
|
||||
}
|
||||
WriteRegion.left = Request->Data.WriteConsoleOutputRequest.WriteRegion.Left;
|
||||
WriteRegion.top = Request->Data.WriteConsoleOutputRequest.WriteRegion.Top;
|
||||
WriteRegion.right = Request->Data.WriteConsoleOutputRequest.WriteRegion.Right;
|
||||
WriteRegion.bottom = Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom;
|
||||
WriteRegion = Request->Data.WriteConsoleOutputRequest.WriteRegion;
|
||||
|
||||
SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion));
|
||||
SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion));
|
||||
WriteRegion.bottom = WriteRegion.top + SizeY - 1;
|
||||
WriteRegion.right = WriteRegion.left + SizeX - 1;
|
||||
WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
|
||||
WriteRegion.Right = WriteRegion.Left + SizeX - 1;
|
||||
|
||||
/* Make sure WriteRegion is inside the screen buffer */
|
||||
ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
|
||||
|
@ -2175,11 +2172,11 @@ CSR_API(CsrWriteConsoleOutput)
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
for (i = 0, Y = WriteRegion.top; Y <= WriteRegion.bottom; i++, Y++)
|
||||
for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++)
|
||||
{
|
||||
CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X;
|
||||
Ptr = ConioCoordToPointer(Buff, WriteRegion.left, Y);
|
||||
for (X = WriteRegion.left; X <= WriteRegion.right; X++)
|
||||
Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y);
|
||||
for (X = WriteRegion.Left; X <= WriteRegion.Right; X++)
|
||||
{
|
||||
CHAR AsciiChar;
|
||||
if (Request->Data.WriteConsoleOutputRequest.Unicode)
|
||||
|
@ -2200,10 +2197,10 @@ CSR_API(CsrWriteConsoleOutput)
|
|||
|
||||
ConioUnlockScreenBuffer(Buff);
|
||||
|
||||
Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.left + SizeX - 1;
|
||||
Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.top + SizeY - 1;
|
||||
Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.left;
|
||||
Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.top;
|
||||
Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.Left + SizeX - 1;
|
||||
Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
|
||||
Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.Left;
|
||||
Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.Top;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -2248,12 +2245,12 @@ CSR_API(CsrScrollConsoleScreenBuffer)
|
|||
{
|
||||
PCSRSS_CONSOLE Console;
|
||||
PCSRSS_SCREEN_BUFFER Buff;
|
||||
RECT ScreenBuffer;
|
||||
RECT SrcRegion;
|
||||
RECT DstRegion;
|
||||
RECT UpdateRegion;
|
||||
RECT ScrollRectangle;
|
||||
RECT ClipRectangle;
|
||||
SMALL_RECT ScreenBuffer;
|
||||
SMALL_RECT SrcRegion;
|
||||
SMALL_RECT DstRegion;
|
||||
SMALL_RECT UpdateRegion;
|
||||
SMALL_RECT ScrollRectangle;
|
||||
SMALL_RECT ClipRectangle;
|
||||
NTSTATUS Status;
|
||||
HANDLE ConsoleHandle;
|
||||
BOOLEAN UseClipRectangle;
|
||||
|
@ -2277,10 +2274,7 @@ CSR_API(CsrScrollConsoleScreenBuffer)
|
|||
}
|
||||
Console = Buff->Header.Console;
|
||||
|
||||
ScrollRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Left;
|
||||
ScrollRectangle.top = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Top;
|
||||
ScrollRectangle.right = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Right;
|
||||
ScrollRectangle.bottom = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Bottom;
|
||||
ScrollRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle;
|
||||
|
||||
/* Make sure source rectangle is inside the screen buffer */
|
||||
ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
|
||||
|
@ -2291,21 +2285,18 @@ CSR_API(CsrScrollConsoleScreenBuffer)
|
|||
}
|
||||
|
||||
/* If the source was clipped on the left or top, adjust the destination accordingly */
|
||||
if (ScrollRectangle.left < 0)
|
||||
if (ScrollRectangle.Left < 0)
|
||||
{
|
||||
DestinationOrigin.X -= ScrollRectangle.left;
|
||||
DestinationOrigin.X -= ScrollRectangle.Left;
|
||||
}
|
||||
if (ScrollRectangle.top < 0)
|
||||
if (ScrollRectangle.Top < 0)
|
||||
{
|
||||
DestinationOrigin.Y -= ScrollRectangle.top;
|
||||
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;
|
||||
ClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle;
|
||||
if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer))
|
||||
{
|
||||
ConioUnlockScreenBuffer(Buff);
|
||||
|
@ -2601,8 +2592,8 @@ CSR_API(CsrReadConsoleOutput)
|
|||
NTSTATUS Status;
|
||||
COORD BufferSize;
|
||||
COORD BufferCoord;
|
||||
RECT ReadRegion;
|
||||
RECT ScreenRect;
|
||||
SMALL_RECT ReadRegion;
|
||||
SMALL_RECT ScreenRect;
|
||||
DWORD i;
|
||||
PBYTE Ptr;
|
||||
LONG X, Y;
|
||||
|
@ -2620,10 +2611,7 @@ CSR_API(CsrReadConsoleOutput)
|
|||
}
|
||||
|
||||
CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo;
|
||||
ReadRegion.left = Request->Data.ReadConsoleOutputRequest.ReadRegion.Left;
|
||||
ReadRegion.top = Request->Data.ReadConsoleOutputRequest.ReadRegion.Top;
|
||||
ReadRegion.right = Request->Data.ReadConsoleOutputRequest.ReadRegion.Right;
|
||||
ReadRegion.bottom = Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom;
|
||||
ReadRegion = Request->Data.ReadConsoleOutputRequest.ReadRegion;
|
||||
BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize;
|
||||
BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord;
|
||||
Length = BufferSize.X * BufferSize.Y;
|
||||
|
@ -2641,8 +2629,8 @@ CSR_API(CsrReadConsoleOutput)
|
|||
|
||||
SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion));
|
||||
SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion));
|
||||
ReadRegion.bottom = ReadRegion.top + SizeY;
|
||||
ReadRegion.right = ReadRegion.left + SizeX;
|
||||
ReadRegion.Bottom = ReadRegion.Top + SizeY;
|
||||
ReadRegion.Right = ReadRegion.Left + SizeX;
|
||||
|
||||
ConioInitRect(&ScreenRect, 0, 0, Buff->MaxY, Buff->MaxX);
|
||||
if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion))
|
||||
|
@ -2651,12 +2639,12 @@ CSR_API(CsrReadConsoleOutput)
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
for (i = 0, Y = ReadRegion.top; Y < ReadRegion.bottom; ++i, ++Y)
|
||||
for (i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y)
|
||||
{
|
||||
CurCharInfo = CharInfo + (i * BufferSize.X);
|
||||
|
||||
Ptr = ConioCoordToPointer(Buff, ReadRegion.left, Y);
|
||||
for (X = ReadRegion.left; X < ReadRegion.right; ++X)
|
||||
Ptr = ConioCoordToPointer(Buff, ReadRegion.Left, Y);
|
||||
for (X = ReadRegion.Left; X < ReadRegion.Right; ++X)
|
||||
{
|
||||
if (Request->Data.ReadConsoleOutputRequest.Unicode)
|
||||
{
|
||||
|
@ -2675,10 +2663,10 @@ CSR_API(CsrReadConsoleOutput)
|
|||
|
||||
ConioUnlockScreenBuffer(Buff);
|
||||
|
||||
Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.left + SizeX - 1;
|
||||
Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.top + SizeY - 1;
|
||||
Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.left;
|
||||
Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.top;
|
||||
Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.Left + SizeX - 1;
|
||||
Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.Top + SizeY - 1;
|
||||
Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.Left;
|
||||
Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.Top;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -3063,4 +3051,23 @@ CSR_API(CsrSetScreenBufferSize)
|
|||
return Status;
|
||||
}
|
||||
|
||||
CSR_API(CsrGetConsoleSelectionInfo)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCSRSS_CONSOLE Console;
|
||||
|
||||
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
||||
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
||||
|
||||
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
memset(&Request->Data.GetConsoleSelectionInfo.Info, 0, sizeof(CONSOLE_SELECTION_INFO));
|
||||
if (Console->Selection.dwFlags != 0)
|
||||
Request->Data.GetConsoleSelectionInfo.Info = Console->Selection;
|
||||
ConioUnlockConsole(Console);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -54,9 +54,9 @@ typedef struct tagCSRSS_CONSOLE *PCSRSS_CONSOLE;
|
|||
typedef struct tagCSRSS_CONSOLE_VTBL
|
||||
{
|
||||
VOID (WINAPI *InitScreenBuffer)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer);
|
||||
VOID (WINAPI *WriteStream)(PCSRSS_CONSOLE Console, RECT *Block, LONG CursorStartX, LONG CursorStartY,
|
||||
VOID (WINAPI *WriteStream)(PCSRSS_CONSOLE Console, SMALL_RECT *Block, LONG CursorStartX, LONG CursorStartY,
|
||||
UINT ScrolledLines, CHAR *Buffer, UINT Length);
|
||||
VOID (WINAPI *DrawRegion)(PCSRSS_CONSOLE Console, RECT *Region);
|
||||
VOID (WINAPI *DrawRegion)(PCSRSS_CONSOLE Console, SMALL_RECT *Region);
|
||||
BOOL (WINAPI *SetCursorInfo)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer);
|
||||
BOOL (WINAPI *SetScreenInfo)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer,
|
||||
UINT OldCursorX, UINT OldCursorY);
|
||||
|
@ -92,6 +92,7 @@ typedef struct tagCSRSS_CONSOLE
|
|||
PCSRSS_CONSOLE_VTBL Vtbl;
|
||||
LIST_ENTRY ProcessList;
|
||||
struct tagALIAS_HEADER *Aliases;
|
||||
CONSOLE_SELECTION_INFO Selection;
|
||||
} CSRSS_CONSOLE;
|
||||
|
||||
typedef struct ConsoleInput_t
|
||||
|
@ -103,6 +104,13 @@ typedef struct ConsoleInput_t
|
|||
BOOLEAN NotChar; // message should not be used to return a character
|
||||
} ConsoleInput;
|
||||
|
||||
/* CONSOLE_SELECTION_INFO dwFlags values */
|
||||
#define CONSOLE_NO_SELECTION 0x0
|
||||
#define CONSOLE_SELECTION_IN_PROGRESS 0x1
|
||||
#define CONSOLE_SELECTION_NOT_EMPTY 0x2
|
||||
#define CONSOLE_MOUSE_SELECTION 0x4
|
||||
#define CONSOLE_MOUSE_DOWN 0x8
|
||||
|
||||
NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console);
|
||||
VOID WINAPI ConioDeleteConsole(Object_t *Object);
|
||||
VOID WINAPI ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer);
|
||||
|
@ -155,6 +163,7 @@ CSR_API(CsrSetConsoleOutputCodePage);
|
|||
CSR_API(CsrGetProcessList);
|
||||
CSR_API(CsrGenerateCtrlEvent);
|
||||
CSR_API(CsrSetScreenBufferSize);
|
||||
CSR_API(CsrGetConsoleSelectionInfo);
|
||||
|
||||
#define ConioInitScreenBuffer(Console, Buff) (Console)->Vtbl->InitScreenBuffer((Console), (Buff))
|
||||
#define ConioDrawRegion(Console, Region) (Console)->Vtbl->DrawRegion((Console), (Region))
|
||||
|
@ -172,9 +181,9 @@ CSR_API(CsrSetScreenBufferSize);
|
|||
#define ConioResizeBuffer(Console, Buff, Size) (Console)->Vtbl->ResizeBuffer(Console, Buff, Size)
|
||||
|
||||
#define ConioRectHeight(Rect) \
|
||||
(((Rect)->top) > ((Rect)->bottom) ? 0 : ((Rect)->bottom) - ((Rect)->top) + 1)
|
||||
(((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) - ((Rect)->Top) + 1)
|
||||
#define ConioRectWidth(Rect) \
|
||||
(((Rect)->left) > ((Rect)->right) ? 0 : ((Rect)->right) - ((Rect)->left) + 1)
|
||||
(((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1)
|
||||
|
||||
#define ConioLockConsole(ProcessData, Handle, Ptr, Access) \
|
||||
Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), Access, CONIO_CONSOLE_MAGIC)
|
||||
|
|
|
@ -81,6 +81,7 @@ static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] =
|
|||
CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES_LENGTH, CsrGetConsoleAliasesExesLength),
|
||||
CSRSS_DEFINE_API(GENERATE_CTRL_EVENT, CsrGenerateCtrlEvent),
|
||||
CSRSS_DEFINE_API(SET_SCREEN_BUFFER_SIZE, CsrSetScreenBufferSize),
|
||||
CSRSS_DEFINE_API(GET_CONSOLE_SELECTION_INFO, CsrGetConsoleSelectionInfo),
|
||||
{ 0, 0, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -25,9 +25,6 @@ typedef struct GUI_CONSOLE_DATA_TAG
|
|||
BOOL CursorBlinkOn;
|
||||
BOOL ForceCursorOff;
|
||||
CRITICAL_SECTION Lock;
|
||||
RECT Selection;
|
||||
POINT SelectionStart;
|
||||
BOOL MouseDown;
|
||||
HMODULE ConsoleLibrary;
|
||||
HANDLE hGuiInitEvent;
|
||||
WCHAR FontName[LF_FACESIZE];
|
||||
|
@ -773,7 +770,6 @@ GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
|
|||
GuiData->CursorBlinkOn = TRUE;
|
||||
GuiData->ForceCursorOff = FALSE;
|
||||
|
||||
GuiData->Selection.left = -1;
|
||||
DPRINT("Console %p GuiData %p\n", Console, GuiData);
|
||||
Console->PrivateData = GuiData;
|
||||
SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console);
|
||||
|
@ -790,40 +786,46 @@ GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
|
|||
return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create);
|
||||
}
|
||||
|
||||
static VOID FASTCALL
|
||||
GuiConsoleUpdateSelection(HWND hWnd, PRECT rc, PGUI_CONSOLE_DATA GuiData)
|
||||
static VOID
|
||||
SmallRectToRect(PCSRSS_CONSOLE Console, PRECT Rect, PSMALL_RECT SmallRect)
|
||||
{
|
||||
RECT oldRect = GuiData->Selection;
|
||||
PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer;
|
||||
PGUI_CONSOLE_DATA GuiData = Console->PrivateData;
|
||||
Rect->left = (SmallRect->Left - Buffer->ShowX) * GuiData->CharWidth;
|
||||
Rect->top = (SmallRect->Top - Buffer->ShowY) * GuiData->CharHeight;
|
||||
Rect->right = (SmallRect->Right + 1 - Buffer->ShowX) * GuiData->CharWidth;
|
||||
Rect->bottom = (SmallRect->Bottom + 1 - Buffer->ShowY) * GuiData->CharHeight;
|
||||
}
|
||||
|
||||
if(rc != NULL)
|
||||
static VOID FASTCALL
|
||||
GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord)
|
||||
{
|
||||
RECT oldRect, newRect;
|
||||
HWND hWnd = Console->hWindow;
|
||||
|
||||
SmallRectToRect(Console, &oldRect, &Console->Selection.srSelection);
|
||||
|
||||
if(coord != NULL)
|
||||
{
|
||||
RECT changeRect = *rc;
|
||||
SMALL_RECT rc;
|
||||
/* exchange left/top with right/bottom if required */
|
||||
rc.Left = min(Console->Selection.dwSelectionAnchor.X, coord->X);
|
||||
rc.Top = min(Console->Selection.dwSelectionAnchor.Y, coord->Y);
|
||||
rc.Right = max(Console->Selection.dwSelectionAnchor.X, coord->X);
|
||||
rc.Bottom = max(Console->Selection.dwSelectionAnchor.Y, coord->Y);
|
||||
|
||||
GuiData->Selection = *rc;
|
||||
SmallRectToRect(Console, &newRect, &rc);
|
||||
|
||||
changeRect.left *= GuiData->CharWidth;
|
||||
changeRect.top *= GuiData->CharHeight;
|
||||
changeRect.right *= GuiData->CharWidth;
|
||||
changeRect.bottom *= GuiData->CharHeight;
|
||||
|
||||
if(rc->left != oldRect.left ||
|
||||
rc->top != oldRect.top ||
|
||||
rc->right != oldRect.right ||
|
||||
rc->bottom != oldRect.bottom)
|
||||
if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
|
||||
{
|
||||
if(oldRect.left != -1)
|
||||
if (memcmp(&rc, &Console->Selection.srSelection, sizeof(SMALL_RECT)) != 0)
|
||||
{
|
||||
HRGN rgn1, rgn2;
|
||||
|
||||
oldRect.left *= GuiData->CharWidth;
|
||||
oldRect.top *= GuiData->CharHeight;
|
||||
oldRect.right *= GuiData->CharWidth;
|
||||
oldRect.bottom *= GuiData->CharHeight;
|
||||
|
||||
/* calculate the region that needs to be updated */
|
||||
if((rgn1 = CreateRectRgnIndirect(&oldRect)))
|
||||
{
|
||||
if((rgn2 = CreateRectRgnIndirect(&changeRect)))
|
||||
if((rgn2 = CreateRectRgnIndirect(&newRect)))
|
||||
{
|
||||
if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR)
|
||||
{
|
||||
|
@ -835,21 +837,22 @@ GuiConsoleUpdateSelection(HWND hWnd, PRECT rc, PGUI_CONSOLE_DATA GuiData)
|
|||
DeleteObject(rgn1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InvalidateRect(hWnd, &changeRect, FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InvalidateRect(hWnd, &newRect, FALSE);
|
||||
}
|
||||
Console->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY;
|
||||
Console->Selection.srSelection = rc;
|
||||
}
|
||||
else if(oldRect.left != -1)
|
||||
else
|
||||
{
|
||||
/* clear the selection */
|
||||
GuiData->Selection.left = -1;
|
||||
oldRect.left *= GuiData->CharWidth;
|
||||
oldRect.top *= GuiData->CharHeight;
|
||||
oldRect.right *= GuiData->CharWidth;
|
||||
oldRect.bottom *= GuiData->CharHeight;
|
||||
InvalidateRect(hWnd, &oldRect, FALSE);
|
||||
if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
|
||||
{
|
||||
InvalidateRect(hWnd, &oldRect, FALSE);
|
||||
}
|
||||
Console->Selection.dwFlags = CONSOLE_NO_SELECTION;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1005,14 +1008,10 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint)
|
|||
hDC,
|
||||
&ps.rcPaint);
|
||||
|
||||
if (GuiData->Selection.left != -1)
|
||||
if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
|
||||
{
|
||||
RECT rc = GuiData->Selection;
|
||||
|
||||
rc.left *= GuiData->CharWidth;
|
||||
rc.top *= GuiData->CharHeight;
|
||||
rc.right *= GuiData->CharWidth;
|
||||
rc.bottom *= GuiData->CharHeight;
|
||||
RECT rc;
|
||||
SmallRectToRect(Console, &rc, &Console->Selection.srSelection);
|
||||
|
||||
/* invert the selection */
|
||||
if (IntersectRect(&rc,
|
||||
|
@ -1052,51 +1051,29 @@ GuiConsoleHandleKey(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
if(msg == WM_CHAR || msg == WM_SYSKEYDOWN)
|
||||
{
|
||||
/* clear the selection */
|
||||
GuiConsoleUpdateSelection(hWnd, NULL, GuiData);
|
||||
GuiConsoleUpdateSelection(Console, NULL);
|
||||
}
|
||||
|
||||
ConioProcessKey(&Message, Console, FALSE);
|
||||
}
|
||||
|
||||
static VOID FASTCALL
|
||||
GuiIntDrawRegion(PCSRSS_SCREEN_BUFFER Buff, PGUI_CONSOLE_DATA GuiData, HWND Wnd, RECT *Region)
|
||||
{
|
||||
RECT RegionRect;
|
||||
|
||||
RegionRect.left = (Region->left - Buff->ShowX) * GuiData->CharWidth;
|
||||
RegionRect.top = (Region->top - Buff->ShowY) * GuiData->CharHeight;
|
||||
RegionRect.right = (Region->right + 1 - Buff->ShowX) * GuiData->CharWidth;
|
||||
RegionRect.bottom = (Region->bottom + 1 - Buff->ShowY) * GuiData->CharHeight;
|
||||
|
||||
InvalidateRect(Wnd, &RegionRect, FALSE);
|
||||
}
|
||||
|
||||
static VOID WINAPI
|
||||
GuiDrawRegion(PCSRSS_CONSOLE Console, RECT *Region)
|
||||
GuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region)
|
||||
{
|
||||
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
|
||||
|
||||
if (NULL != Console->hWindow && NULL != GuiData)
|
||||
{
|
||||
GuiIntDrawRegion(Console->ActiveBuffer, GuiData, Console->hWindow, Region);
|
||||
}
|
||||
RECT RegionRect;
|
||||
SmallRectToRect(Console, &RegionRect, Region);
|
||||
InvalidateRect(Console->hWindow, &RegionRect, FALSE);
|
||||
}
|
||||
|
||||
static VOID FASTCALL
|
||||
GuiInvalidateCell(PCSRSS_SCREEN_BUFFER Buff, PGUI_CONSOLE_DATA GuiData, HWND Wnd, UINT x, UINT y)
|
||||
GuiInvalidateCell(PCSRSS_CONSOLE Console, UINT x, UINT y)
|
||||
{
|
||||
RECT CellRect;
|
||||
|
||||
CellRect.left = x;
|
||||
CellRect.top = y;
|
||||
CellRect.right = x;
|
||||
CellRect.bottom = y;
|
||||
|
||||
GuiIntDrawRegion(Buff, GuiData, Wnd, &CellRect);
|
||||
SMALL_RECT CellRect = { x, y, x, y };
|
||||
GuiDrawRegion(Console, &CellRect);
|
||||
}
|
||||
|
||||
static VOID WINAPI
|
||||
GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG CursorStartY,
|
||||
GuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LONG CursorStartY,
|
||||
UINT ScrolledLines, CHAR *Buffer, UINT Length)
|
||||
{
|
||||
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
|
||||
|
@ -1114,26 +1091,7 @@ GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG Cur
|
|||
ScrollRect.left = 0;
|
||||
ScrollRect.top = 0;
|
||||
ScrollRect.right = Console->Size.X * GuiData->CharWidth;
|
||||
ScrollRect.bottom = Region->top * GuiData->CharHeight;
|
||||
|
||||
if (GuiData->Selection.left != -1)
|
||||
{
|
||||
/* scroll the selection */
|
||||
if (GuiData->Selection.top > ScrolledLines)
|
||||
{
|
||||
GuiData->Selection.top -= ScrolledLines;
|
||||
GuiData->Selection.bottom -= ScrolledLines;
|
||||
}
|
||||
else if (GuiData->Selection.bottom < ScrolledLines)
|
||||
{
|
||||
GuiData->Selection.left = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
GuiData->Selection.top = 0;
|
||||
GuiData->Selection.bottom -= ScrolledLines;
|
||||
}
|
||||
}
|
||||
ScrollRect.bottom = Region->Top * GuiData->CharHeight;
|
||||
|
||||
ScrollWindowEx(Console->hWindow,
|
||||
0,
|
||||
|
@ -1145,21 +1103,21 @@ GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG Cur
|
|||
SW_INVALIDATE);
|
||||
}
|
||||
|
||||
GuiIntDrawRegion(Buff, GuiData, Console->hWindow, Region);
|
||||
GuiDrawRegion(Console, Region);
|
||||
|
||||
if (CursorStartX < Region->left || Region->right < CursorStartX
|
||||
|| CursorStartY < Region->top || Region->bottom < CursorStartY)
|
||||
if (CursorStartX < Region->Left || Region->Right < CursorStartX
|
||||
|| CursorStartY < Region->Top || Region->Bottom < CursorStartY)
|
||||
{
|
||||
GuiInvalidateCell(Buff, GuiData, Console->hWindow, CursorStartX, CursorStartY);
|
||||
GuiInvalidateCell(Console, CursorStartX, CursorStartY);
|
||||
}
|
||||
|
||||
CursorEndX = Buff->CurrentX;
|
||||
CursorEndY = Buff->CurrentY;
|
||||
if ((CursorEndX < Region->left || Region->right < CursorEndX
|
||||
|| CursorEndY < Region->top || Region->bottom < CursorEndY)
|
||||
if ((CursorEndX < Region->Left || Region->Right < CursorEndX
|
||||
|| CursorEndY < Region->Top || Region->Bottom < CursorEndY)
|
||||
&& (CursorEndX != CursorStartX || CursorEndY != CursorStartY))
|
||||
{
|
||||
GuiInvalidateCell(Buff, GuiData, Console->hWindow, CursorEndX, CursorEndY);
|
||||
GuiInvalidateCell(Console, CursorEndX, CursorEndY);
|
||||
}
|
||||
|
||||
// Set up the update timer (very short interval) - this is a "hack" for getting the OS to
|
||||
|
@ -1171,15 +1129,9 @@ GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG Cur
|
|||
static BOOL WINAPI
|
||||
GuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
|
||||
{
|
||||
RECT UpdateRect;
|
||||
|
||||
if (Console->ActiveBuffer == Buff)
|
||||
{
|
||||
UpdateRect.left = Buff->CurrentX;
|
||||
UpdateRect.top = Buff->CurrentY;
|
||||
UpdateRect.right = UpdateRect.left;
|
||||
UpdateRect.bottom = UpdateRect.top;
|
||||
ConioDrawRegion(Console, &UpdateRect);
|
||||
GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -1188,22 +1140,12 @@ GuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
|
|||
static BOOL WINAPI
|
||||
GuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY)
|
||||
{
|
||||
RECT UpdateRect;
|
||||
|
||||
if (Console->ActiveBuffer == Buff)
|
||||
{
|
||||
/* Redraw char at old position (removes cursor) */
|
||||
UpdateRect.left = OldCursorX;
|
||||
UpdateRect.top = OldCursorY;
|
||||
UpdateRect.right = OldCursorX;
|
||||
UpdateRect.bottom = OldCursorY;
|
||||
ConioDrawRegion(Console, &UpdateRect);
|
||||
GuiInvalidateCell(Console, OldCursorX, OldCursorY);
|
||||
/* Redraw char at new position (shows cursor) */
|
||||
UpdateRect.left = Buff->CurrentX;
|
||||
UpdateRect.top = Buff->CurrentY;
|
||||
UpdateRect.right = UpdateRect.left;
|
||||
UpdateRect.bottom = UpdateRect.top;
|
||||
ConioDrawRegion(Console, &UpdateRect);
|
||||
GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -1229,18 +1171,13 @@ GuiConsoleHandleTimer(HWND hWnd)
|
|||
PCSRSS_CONSOLE Console;
|
||||
PGUI_CONSOLE_DATA GuiData;
|
||||
PCSRSS_SCREEN_BUFFER Buff;
|
||||
RECT CursorRect;
|
||||
|
||||
SetTimer(hWnd, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL);
|
||||
|
||||
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
|
||||
|
||||
Buff = Console->ActiveBuffer;
|
||||
CursorRect.left = Buff->CurrentX;
|
||||
CursorRect.top = Buff->CurrentY;
|
||||
CursorRect.right = CursorRect.left;
|
||||
CursorRect.bottom = CursorRect.top;
|
||||
GuiDrawRegion(Console, &CursorRect);
|
||||
GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY);
|
||||
GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn;
|
||||
|
||||
if((GuiData->OldCursor.x != Buff->CurrentX) || (GuiData->OldCursor.y != Buff->CurrentY))
|
||||
|
@ -1362,32 +1299,39 @@ GuiConsoleHandleNcDestroy(HWND hWnd)
|
|||
HeapFree(Win32CsrApiHeap, 0, GuiData);
|
||||
}
|
||||
|
||||
static COORD
|
||||
PointToCoord(PCSRSS_CONSOLE Console, LPARAM lParam)
|
||||
{
|
||||
PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer;
|
||||
PGUI_CONSOLE_DATA GuiData = Console->PrivateData;
|
||||
COORD Coord;
|
||||
Coord.X = Buffer->ShowX + ((short)LOWORD(lParam) / (int)GuiData->CharWidth);
|
||||
Coord.Y = Buffer->ShowY + ((short)HIWORD(lParam) / (int)GuiData->CharHeight);
|
||||
|
||||
/* Clip coordinate to ensure it's inside buffer */
|
||||
if (Coord.X < 0) Coord.X = 0;
|
||||
else if (Coord.X >= Buffer->MaxX) Coord.X = Buffer->MaxX - 1;
|
||||
if (Coord.Y < 0) Coord.Y = 0;
|
||||
else if (Coord.Y >= Buffer->MaxY) Coord.Y = Buffer->MaxY - 1;
|
||||
return Coord;
|
||||
}
|
||||
|
||||
static VOID FASTCALL
|
||||
GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam)
|
||||
{
|
||||
PCSRSS_CONSOLE Console;
|
||||
PGUI_CONSOLE_DATA GuiData;
|
||||
POINTS pt;
|
||||
RECT rc;
|
||||
|
||||
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
|
||||
if (Console == NULL || GuiData == NULL) return;
|
||||
|
||||
pt = MAKEPOINTS(lParam);
|
||||
|
||||
rc.left = pt.x / GuiData->CharWidth;
|
||||
rc.top = pt.y / GuiData->CharHeight;
|
||||
rc.right = rc.left + 1;
|
||||
rc.bottom = rc.top + 1;
|
||||
|
||||
GuiData->SelectionStart.x = rc.left;
|
||||
GuiData->SelectionStart.y = rc.top;
|
||||
Console->Selection.dwSelectionAnchor = PointToCoord(Console, lParam);
|
||||
|
||||
SetCapture(hWnd);
|
||||
|
||||
GuiData->MouseDown = TRUE;
|
||||
Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS | CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN;
|
||||
|
||||
GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
|
||||
GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor);
|
||||
}
|
||||
|
||||
static VOID FASTCALL
|
||||
|
@ -1395,39 +1339,17 @@ GuiConsoleLeftMouseUp(HWND hWnd, LPARAM lParam)
|
|||
{
|
||||
PCSRSS_CONSOLE Console;
|
||||
PGUI_CONSOLE_DATA GuiData;
|
||||
RECT rc;
|
||||
POINTS pt;
|
||||
COORD c;
|
||||
|
||||
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
|
||||
if (Console == NULL || GuiData == NULL) return;
|
||||
if (GuiData->Selection.left == -1 || !GuiData->MouseDown) return;
|
||||
if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return;
|
||||
|
||||
pt = MAKEPOINTS(lParam);
|
||||
c = PointToCoord(Console, lParam);
|
||||
|
||||
rc.left = GuiData->SelectionStart.x;
|
||||
rc.top = GuiData->SelectionStart.y;
|
||||
rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0);
|
||||
rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0);
|
||||
Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN;
|
||||
|
||||
/* exchange left/top with right/bottom if required */
|
||||
if(rc.left >= rc.right)
|
||||
{
|
||||
LONG tmp;
|
||||
tmp = rc.left;
|
||||
rc.left = max(rc.right - 1, 0);
|
||||
rc.right = tmp + 1;
|
||||
}
|
||||
if(rc.top >= rc.bottom)
|
||||
{
|
||||
LONG tmp;
|
||||
tmp = rc.top;
|
||||
rc.top = max(rc.bottom - 1, 0);
|
||||
rc.bottom = tmp + 1;
|
||||
}
|
||||
|
||||
GuiData->MouseDown = FALSE;
|
||||
|
||||
GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
|
||||
GuiConsoleUpdateSelection(Console, &c);
|
||||
|
||||
ReleaseCapture();
|
||||
}
|
||||
|
@ -1437,46 +1359,17 @@ GuiConsoleMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||
{
|
||||
PCSRSS_CONSOLE Console;
|
||||
PGUI_CONSOLE_DATA GuiData;
|
||||
RECT rc;
|
||||
POINTS pt;
|
||||
COORD c;
|
||||
|
||||
if (!(wParam & MK_LBUTTON)) return;
|
||||
|
||||
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
|
||||
if (Console == NULL || GuiData == NULL || !GuiData->MouseDown) return;
|
||||
if (Console == NULL || GuiData == NULL) return;
|
||||
if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return;
|
||||
|
||||
pt = MAKEPOINTS(lParam);
|
||||
c = PointToCoord(Console, lParam); /* TODO: Scroll buffer to bring c into view */
|
||||
|
||||
rc.left = GuiData->SelectionStart.x;
|
||||
rc.top = GuiData->SelectionStart.y;
|
||||
rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0);
|
||||
if (Console->Size.X < rc.right)
|
||||
{
|
||||
rc.right = Console->Size.X;
|
||||
}
|
||||
rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0);
|
||||
if (Console->Size.Y < rc.bottom)
|
||||
{
|
||||
rc.bottom = Console->Size.Y;
|
||||
}
|
||||
|
||||
/* exchange left/top with right/bottom if required */
|
||||
if(rc.left >= rc.right)
|
||||
{
|
||||
LONG tmp;
|
||||
tmp = rc.left;
|
||||
rc.left = max(rc.right - 1, 0);
|
||||
rc.right = tmp + 1;
|
||||
}
|
||||
if(rc.top >= rc.bottom)
|
||||
{
|
||||
LONG tmp;
|
||||
tmp = rc.top;
|
||||
rc.top = max(rc.bottom - 1, 0);
|
||||
rc.bottom = tmp + 1;
|
||||
}
|
||||
|
||||
GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
|
||||
GuiConsoleUpdateSelection(Console, &c);
|
||||
}
|
||||
|
||||
static VOID FASTCALL
|
||||
|
@ -1488,7 +1381,7 @@ GuiConsoleRightMouseDown(HWND hWnd)
|
|||
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
|
||||
if (Console == NULL || GuiData == NULL) return;
|
||||
|
||||
if (GuiData->Selection.left == -1)
|
||||
if (!(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY))
|
||||
{
|
||||
/* FIXME - paste text from clipboard */
|
||||
}
|
||||
|
@ -1496,7 +1389,7 @@ GuiConsoleRightMouseDown(HWND hWnd)
|
|||
{
|
||||
/* FIXME - copy selection to clipboard */
|
||||
|
||||
GuiConsoleUpdateSelection(hWnd, NULL, GuiData);
|
||||
GuiConsoleUpdateSelection(Console, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue