From 7fa77031b0003ce69f23735cbf91a5e6a9f146be Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sun, 23 May 2010 22:38:16 +0000 Subject: [PATCH] [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 --- reactos/dll/win32/kernel32/misc/console.c | 16 +- reactos/include/reactos/subsys/csrss/csrss.h | 7 + .../subsystems/win32/csrss/win32csr/conio.c | 249 ++++++++------- .../subsystems/win32/csrss/win32csr/conio.h | 17 +- .../subsystems/win32/csrss/win32csr/dllmain.c | 1 + .../win32/csrss/win32csr/guiconsole.c | 297 ++++++------------ 6 files changed, 256 insertions(+), 331 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/console.c b/reactos/dll/win32/kernel32/misc/console.c index 2d6d5ba8643..298f79b8e59 100644 --- a/reactos/dll/win32/kernel32/misc/console.c +++ b/reactos/dll/win32/kernel32/misc/console.c @@ -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; } diff --git a/reactos/include/reactos/subsys/csrss/csrss.h b/reactos/include/reactos/subsys/csrss/csrss.h index b1867e49f26..62fe387633c 100644 --- a/reactos/include/reactos/subsys/csrss/csrss.h +++ b/reactos/include/reactos/subsys/csrss/csrss.h @@ -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; diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index 579e4fe07fb..60b93cf9b3f 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -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 */ diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.h b/reactos/subsystems/win32/csrss/win32csr/conio.h index 8c853689b30..8645351f96a 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.h +++ b/reactos/subsystems/win32/csrss/win32csr/conio.h @@ -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) diff --git a/reactos/subsystems/win32/csrss/win32csr/dllmain.c b/reactos/subsystems/win32/csrss/win32csr/dllmain.c index bd0409c55ca..2e8947f014a 100644 --- a/reactos/subsystems/win32/csrss/win32csr/dllmain.c +++ b/reactos/subsystems/win32/csrss/win32csr/dllmain.c @@ -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 } }; diff --git a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c index 3edccbc7764..0d063d8b31b 100644 --- a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c +++ b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c @@ -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 +SmallRectToRect(PCSRSS_CONSOLE Console, PRECT Rect, PSMALL_RECT SmallRect) +{ + 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; +} + static VOID FASTCALL -GuiConsoleUpdateSelection(HWND hWnd, PRECT rc, PGUI_CONSOLE_DATA GuiData) +GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord) { - RECT oldRect = GuiData->Selection; + RECT oldRect, newRect; + HWND hWnd = Console->hWindow; - if(rc != NULL) - { - RECT changeRect = *rc; + SmallRectToRect(Console, &oldRect, &Console->Selection.srSelection); - GuiData->Selection = *rc; + if(coord != NULL) + { + 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); - changeRect.left *= GuiData->CharWidth; - changeRect.top *= GuiData->CharHeight; - changeRect.right *= GuiData->CharWidth; - changeRect.bottom *= GuiData->CharHeight; + SmallRectToRect(Console, &newRect, &rc); - 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; - - pt = MAKEPOINTS(lParam); - - 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; - } + if (Console == NULL || GuiData == NULL) return; + if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return; - /* 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; - } + c = PointToCoord(Console, lParam); /* TODO: Scroll buffer to bring c into view */ - 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); } } -- 2.17.1