static NTSTATUS ConioAddInputEvents(PCONSRV_CONSOLE Console, PINPUT_RECORD InputRecords, // InputEvent ULONG NumEventsToWrite, PULONG NumEventsWritten, BOOLEAN AppendToEnd) { NTSTATUS Status = STATUS_SUCCESS; if (NumEventsWritten) *NumEventsWritten = 0; NumEventsToWrite = PreprocessInput(Console, InputRecords, NumEventsToWrite); if (NumEventsToWrite == 0) return STATUS_SUCCESS; // Status = ConDrvAddInputEvents(Console, // InputRecords, // NumEventsToWrite, // NumEventsWritten, // AppendToEnd); Status = ConDrvWriteConsoleInput((PCONSOLE)Console, &Console->InputBuffer, AppendToEnd, InputRecords, NumEventsToWrite, NumEventsWritten); // if (NT_SUCCESS(Status)) if (Status == STATUS_SUCCESS) PostprocessInput(Console); return Status; }
NTSTATUS ConioResizeBuffer(PCONSOLE Console, PTEXTMODE_SCREEN_BUFFER ScreenBuffer, COORD Size) { PCHAR_INFO Buffer; DWORD Offset = 0; PCHAR_INFO ptr; WORD CurrentAttribute; USHORT CurrentY; PCHAR_INFO OldBuffer; DWORD i; DWORD diff; /* Buffer size is not allowed to be smaller than the view size */ if (Size.X < ScreenBuffer->ViewSize.X || Size.Y < ScreenBuffer->ViewSize.Y) return STATUS_INVALID_PARAMETER; if (Size.X == ScreenBuffer->ScreenBufferSize.X && Size.Y == ScreenBuffer->ScreenBufferSize.Y) { // FIXME: Trigger a buffer resize event ?? return STATUS_SUCCESS; } if (Console->FixedSize) { /* * The console is in fixed-size mode, so we cannot resize anything * at the moment. However, keep those settings somewhere so that * we can try to set them up when we will be allowed to do so. */ ScreenBuffer->OldScreenBufferSize = Size; return STATUS_NOT_SUPPORTED; // STATUS_SUCCESS } Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Size.X * Size.Y * sizeof(CHAR_INFO)); if (!Buffer) return STATUS_NO_MEMORY; DPRINT("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->ScreenBufferSize.X, ScreenBuffer->ScreenBufferSize.Y, Size.X, Size.Y); OldBuffer = ScreenBuffer->Buffer; for (CurrentY = 0; CurrentY < ScreenBuffer->ScreenBufferSize.Y && CurrentY < Size.Y; CurrentY++) { ptr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY); if (Size.X <= ScreenBuffer->ScreenBufferSize.X) { /* Reduce size */ RtlCopyMemory(Buffer + Offset, ptr, Size.X * sizeof(CHAR_INFO)); Offset += Size.X; } else { /* Enlarge size */ RtlCopyMemory(Buffer + Offset, ptr, ScreenBuffer->ScreenBufferSize.X * sizeof(CHAR_INFO)); Offset += ScreenBuffer->ScreenBufferSize.X; /* The attribute to be used is the one of the last cell of the current line */ CurrentAttribute = ConioCoordToPointer(ScreenBuffer, ScreenBuffer->ScreenBufferSize.X - 1, CurrentY)->Attributes; diff = Size.X - ScreenBuffer->ScreenBufferSize.X; /* Zero-out the new part of the buffer */ for (i = 0; i < diff; i++) { ptr = Buffer + Offset; ptr->Char.UnicodeChar = L' '; ptr->Attributes = CurrentAttribute; ++Offset; } } } if (Size.Y > ScreenBuffer->ScreenBufferSize.Y) { diff = Size.X * (Size.Y - ScreenBuffer->ScreenBufferSize.Y); /* Zero-out the new part of the buffer */ for (i = 0; i < diff; i++) { ptr = Buffer + Offset; ptr->Char.UnicodeChar = L' '; ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib; ++Offset; } } (void)InterlockedExchangePointer((PVOID volatile*)&ScreenBuffer->Buffer, Buffer); ConsoleFreeHeap(OldBuffer); ScreenBuffer->ScreenBufferSize = ScreenBuffer->OldScreenBufferSize = Size; ScreenBuffer->VirtualY = 0; /* Ensure cursor and window are within buffer */ if (ScreenBuffer->CursorPosition.X >= Size.X) ScreenBuffer->CursorPosition.X = Size.X - 1; if (ScreenBuffer->CursorPosition.Y >= Size.Y) ScreenBuffer->CursorPosition.Y = Size.Y - 1; if (ScreenBuffer->ViewOrigin.X > Size.X - ScreenBuffer->ViewSize.X) ScreenBuffer->ViewOrigin.X = Size.X - ScreenBuffer->ViewSize.X; if (ScreenBuffer->ViewOrigin.Y > Size.Y - ScreenBuffer->ViewSize.Y) ScreenBuffer->ViewOrigin.Y = Size.Y - ScreenBuffer->ViewSize.Y; /* * Trigger a buffer resize event */ if (Console->InputBuffer.Mode & ENABLE_WINDOW_INPUT) { ULONG NumEventsWritten; INPUT_RECORD er; er.EventType = WINDOW_BUFFER_SIZE_EVENT; er.Event.WindowBufferSizeEvent.dwSize = ScreenBuffer->ScreenBufferSize; // ConioProcessInputEvent(Console, &er); ConDrvWriteConsoleInput(Console, &Console->InputBuffer, TRUE, &er, 1, &NumEventsWritten); } return STATUS_SUCCESS; }