3 * Copyright (C) 2002 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/console.c
23 * PURPOSE: Console support functions
24 * PROGRAMMER: Eric Kohl
27 /* INCLUDES ******************************************************************/
30 #include <ddk/ntddblue.h>
39 /* GLOBALS ******************************************************************/
41 static HANDLE StdInput
= INVALID_HANDLE_VALUE
;
42 static HANDLE StdOutput
= INVALID_HANDLE_VALUE
;
44 static SHORT xScreen
= 0;
45 static SHORT yScreen
= 0;
49 GetConsoleScreenBufferInfo(PCONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo
);
52 /* FUNCTIONS *****************************************************************/
59 OBJECT_ATTRIBUTES ObjectAttributes
;
60 IO_STATUS_BLOCK IoStatusBlock
;
63 CONSOLE_SCREEN_BUFFER_INFO csbi
;
66 RtlInitUnicodeString(&Name
,
68 InitializeObjectAttributes(&ObjectAttributes
,
73 Status
= NtOpenFile (&StdOutput
,
78 FILE_SYNCHRONOUS_IO_ALERT
);
79 if (!NT_SUCCESS(Status
))
82 /* Open the keyboard */
83 RtlInitUnicodeString(&Name
,
85 InitializeObjectAttributes(&ObjectAttributes
,
90 Status
= NtOpenFile (&StdInput
,
95 FILE_SYNCHRONOUS_IO_ALERT
);
96 if (!NT_SUCCESS(Status
))
99 GetConsoleScreenBufferInfo(&csbi
);
101 xScreen
= csbi
.dwSize
.X
;
102 yScreen
= csbi
.dwSize
.Y
;
111 DPRINT("FreeConsole() called\n");
113 if (StdInput
!= INVALID_HANDLE_VALUE
)
116 if (StdOutput
!= INVALID_HANDLE_VALUE
)
119 DPRINT("FreeConsole() done\n");
126 WriteConsole(PCHAR Buffer
,
127 ULONG NumberOfCharsToWrite
,
128 PULONG NumberOfCharsWritten
)
130 IO_STATUS_BLOCK IoStatusBlock
;
131 NTSTATUS Status
= STATUS_SUCCESS
;
133 Status
= NtWriteFile(StdOutput
,
139 NumberOfCharsToWrite
,
143 if (NT_SUCCESS(Status
) && NumberOfCharsWritten
!= NULL
)
145 *NumberOfCharsWritten
= IoStatusBlock
.Information
;
153 /*--------------------------------------------------------------
158 ReadConsoleA(HANDLE hConsoleInput
,
160 DWORD nNumberOfCharsToRead
,
161 LPDWORD lpNumberOfCharsRead
,
164 KEY_EVENT_RECORD KeyEventRecord
;
166 PCHAR Buffer
= (PCHAR
)lpBuffer
;
170 for (i
=0; (stat
&& i
<nNumberOfCharsToRead
);)
172 stat
= ReadFile(hConsoleInput
,
174 sizeof(KEY_EVENT_RECORD
),
177 if (stat
&& KeyEventRecord
.bKeyDown
&& KeyEventRecord
.uChar
.AsciiChar
!= 0)
179 Buffer
[i
] = KeyEventRecord
.uChar
.AsciiChar
;
183 if (lpNumberOfCharsRead
!= NULL
)
185 *lpNumberOfCharsRead
= i
;
193 ReadConsoleInput(PINPUT_RECORD Buffer
)
195 IO_STATUS_BLOCK Iosb
;
198 Buffer
->EventType
= KEY_EVENT
;
199 Status
= NtReadFile(StdInput
,
204 &Buffer
->Event
.KeyEvent
,
205 sizeof(KEY_EVENT_RECORD
),
214 ReadConsoleOutputCharacters(LPSTR lpCharacter
,
217 PULONG lpNumberOfCharsRead
)
219 IO_STATUS_BLOCK IoStatusBlock
;
220 OUTPUT_CHARACTER Buffer
;
223 Buffer
.dwCoord
= dwReadCoord
;
225 Status
= NtDeviceIoControlFile(StdOutput
,
230 IOCTL_CONSOLE_READ_OUTPUT_CHARACTER
,
232 sizeof(OUTPUT_CHARACTER
),
236 if (NT_SUCCESS(Status
) && lpNumberOfCharsRead
!= NULL
)
238 *lpNumberOfCharsRead
= Buffer
.dwTransfered
;
246 ReadConsoleOutputAttributes(PUSHORT lpAttribute
,
249 PULONG lpNumberOfAttrsRead
)
251 IO_STATUS_BLOCK IoStatusBlock
;
252 OUTPUT_ATTRIBUTE Buffer
;
255 Buffer
.dwCoord
= dwReadCoord
;
257 Status
= NtDeviceIoControlFile(StdOutput
,
262 IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
,
264 sizeof(OUTPUT_ATTRIBUTE
),
268 if (NT_SUCCESS(Status
) && lpNumberOfAttrsRead
!= NULL
)
270 *lpNumberOfAttrsRead
= Buffer
.dwTransfered
;
278 WriteConsoleOutputCharacters(LPCSTR lpCharacter
,
282 IO_STATUS_BLOCK IoStatusBlock
;
288 Buffer
= RtlAllocateHeap(ProcessHeap
,
290 nLength
+ sizeof(COORD
));
291 pCoord
= (COORD
*)Buffer
;
292 pText
= (PCHAR
)(pCoord
+ 1);
294 *pCoord
= dwWriteCoord
;
295 memcpy(pText
, lpCharacter
, nLength
);
297 Status
= NtDeviceIoControlFile(StdOutput
,
302 IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
,
306 nLength
+ sizeof(COORD
));
308 RtlFreeHeap(ProcessHeap
,
317 WriteConsoleOutputCharactersW(LPCWSTR lpCharacter
,
321 IO_STATUS_BLOCK IoStatusBlock
;
328 Buffer
= RtlAllocateHeap(ProcessHeap
,
330 nLength
+ sizeof(COORD
));
331 pCoord
= (COORD
*)Buffer
;
332 pText
= (PCHAR
)(pCoord
+ 1);
334 *pCoord
= dwWriteCoord
;
336 /* FIXME: use real unicode->oem conversion */
337 for (i
= 0; i
< nLength
; i
++)
338 pText
[i
] = (CHAR
)lpCharacter
[i
];
341 Status
= NtDeviceIoControlFile(StdOutput
,
346 IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
,
350 nLength
+ sizeof(COORD
));
352 RtlFreeHeap(ProcessHeap
,
361 WriteConsoleOutputAttributes(CONST USHORT
*lpAttribute
,
364 PULONG lpNumberOfAttrsWritten
)
366 IO_STATUS_BLOCK IoStatusBlock
;
372 Buffer
= RtlAllocateHeap(ProcessHeap
,
374 nLength
* sizeof(USHORT
) + sizeof(COORD
));
375 pCoord
= (COORD
*)Buffer
;
376 pAttrib
= (PUSHORT
)(pCoord
+ 1);
378 *pCoord
= dwWriteCoord
;
379 memcpy(pAttrib
, lpAttribute
, nLength
* sizeof(USHORT
));
381 Status
= NtDeviceIoControlFile(StdOutput
,
386 IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
,
390 nLength
* sizeof(USHORT
) + sizeof(COORD
));
392 RtlFreeHeap(ProcessHeap
,
401 FillConsoleOutputAttribute(USHORT wAttribute
,
404 PULONG lpNumberOfAttrsWritten
)
406 IO_STATUS_BLOCK IoStatusBlock
;
407 OUTPUT_ATTRIBUTE Buffer
;
410 Buffer
.wAttribute
= wAttribute
;
411 Buffer
.nLength
= nLength
;
412 Buffer
.dwCoord
= dwWriteCoord
;
414 Status
= NtDeviceIoControlFile(StdOutput
,
419 IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
,
421 sizeof(OUTPUT_ATTRIBUTE
),
423 sizeof(OUTPUT_ATTRIBUTE
));
425 if (NT_SUCCESS(Status
))
427 *lpNumberOfAttrsWritten
= Buffer
.dwTransfered
;
435 FillConsoleOutputCharacter(CHAR Character
,
438 PULONG NumberOfCharsWritten
)
440 IO_STATUS_BLOCK IoStatusBlock
;
441 OUTPUT_CHARACTER Buffer
;
444 Buffer
.cCharacter
= Character
;
445 Buffer
.nLength
= Length
;
446 Buffer
.dwCoord
= WriteCoord
;
448 Status
= NtDeviceIoControlFile(StdOutput
,
453 IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
,
455 sizeof(OUTPUT_CHARACTER
),
457 sizeof(OUTPUT_CHARACTER
));
459 if (NT_SUCCESS(Status
))
461 *NumberOfCharsWritten
= Buffer
.dwTransfered
;
469 /*--------------------------------------------------------------
476 HANDLE hConsoleHandle
,
481 DWORD dwBytesReturned
;
483 if (DeviceIoControl (hConsoleHandle
,
484 IOCTL_CONSOLE_GET_MODE
,
488 sizeof(CONSOLE_MODE
),
492 *lpMode
= Buffer
.dwMode
;
493 SetLastError (ERROR_SUCCESS
);
497 SetLastError(0); /* FIXME: What error code? */
502 /*--------------------------------------------------------------
503 * GetConsoleCursorInfo
508 GetConsoleCursorInfo(
509 HANDLE hConsoleOutput
,
510 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
513 DWORD dwBytesReturned
;
515 if (DeviceIoControl (hConsoleOutput
,
516 IOCTL_CONSOLE_GET_CURSOR_INFO
,
520 sizeof(CONSOLE_CURSOR_INFO
),
530 SetConsoleMode(HANDLE hConsoleHandle
,
533 IO_STATUS_BLOCK IoStatusBlock
;
537 Buffer
.dwMode
= dwMode
;
539 Status
= NtDeviceIoControlFile(hConsoleHandle
,
544 IOCTL_CONSOLE_SET_MODE
,
546 sizeof(CONSOLE_MODE
),
556 GetConsoleScreenBufferInfo(PCONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo
)
558 IO_STATUS_BLOCK IoStatusBlock
;
561 Status
= NtDeviceIoControlFile(StdOutput
,
566 IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
,
569 ConsoleScreenBufferInfo
,
570 sizeof(CONSOLE_SCREEN_BUFFER_INFO
));
577 SetConsoleCursorInfo(PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
)
579 IO_STATUS_BLOCK IoStatusBlock
;
582 Status
= NtDeviceIoControlFile(StdOutput
,
587 IOCTL_CONSOLE_SET_CURSOR_INFO
,
588 (PCONSOLE_CURSOR_INFO
)lpConsoleCursorInfo
,
589 sizeof(CONSOLE_CURSOR_INFO
),
598 SetConsoleCursorPosition(COORD dwCursorPosition
)
600 CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo
;
601 IO_STATUS_BLOCK IoStatusBlock
;
604 Status
= GetConsoleScreenBufferInfo(&ConsoleScreenBufferInfo
);
605 if (!NT_SUCCESS(Status
))
608 ConsoleScreenBufferInfo
.dwCursorPosition
.X
= dwCursorPosition
.X
;
609 ConsoleScreenBufferInfo
.dwCursorPosition
.Y
= dwCursorPosition
.Y
;
611 Status
= NtDeviceIoControlFile(StdOutput
,
616 IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
,
617 &ConsoleScreenBufferInfo
,
618 sizeof(CONSOLE_SCREEN_BUFFER_INFO
),
627 SetConsoleTextAttribute(USHORT wAttributes
)
629 IO_STATUS_BLOCK IoStatusBlock
;
632 Status
= NtDeviceIoControlFile(StdOutput
,
637 IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
,
650 ConInKey(PINPUT_RECORD Buffer
)
655 ReadConsoleInput(Buffer
);
657 if ((Buffer
->EventType
== KEY_EVENT
) &&
658 (Buffer
->Event
.KeyEvent
.bKeyDown
== TRUE
))
676 ConOutPuts(LPSTR szText
)
690 ConOutPrintf(LPSTR szFormat
, ...)
696 va_start(arg_ptr
, szFormat
);
697 vsprintf(szOut
, szFormat
, arg_ptr
);
712 CONSOLE_SCREEN_BUFFER_INFO csbi
;
714 GetConsoleScreenBufferInfo(&csbi
);
716 return(csbi
.dwCursorPosition
.X
);
723 CONSOLE_SCREEN_BUFFER_INFO csbi
;
725 GetConsoleScreenBufferInfo(&csbi
);
727 return(csbi
.dwCursorPosition
.Y
);
732 GetScreenSize(SHORT
*maxx
,
735 CONSOLE_SCREEN_BUFFER_INFO csbi
;
737 GetConsoleScreenBufferInfo(&csbi
);
740 *maxx
= csbi
.dwSize
.X
;
743 *maxy
= csbi
.dwSize
.Y
;
748 SetCursorType(BOOL bInsert
,
751 CONSOLE_CURSOR_INFO cci
;
753 cci
.dwSize
= bInsert
? 10 : 99;
754 cci
.bVisible
= bVisible
;
756 SetConsoleCursorInfo(&cci
);
768 SetConsoleCursorPosition(coPos
);
781 FillConsoleOutputAttribute(0x17,
786 FillConsoleOutputCharacter(' ',
794 SetStatusText(char* fmt
, ...)
802 vsprintf(Buffer
, fmt
, ap
);
806 coPos
.Y
= yScreen
- 1;
808 FillConsoleOutputAttribute(0x70,
813 FillConsoleOutputCharacter(' ',
818 WriteConsoleOutputCharacters(Buffer
,
825 InvertTextXY(SHORT x
, SHORT y
, SHORT col
, SHORT row
)
830 for (coPos
.Y
= y
; coPos
.Y
< y
+ row
; coPos
.Y
++)
834 FillConsoleOutputAttribute(0x71,
843 NormalTextXY(SHORT x
, SHORT y
, SHORT col
, SHORT row
)
848 for (coPos
.Y
= y
; coPos
.Y
< y
+ row
; coPos
.Y
++)
852 FillConsoleOutputAttribute(0x17,
861 SetTextXY(SHORT x
, SHORT y
, PCHAR Text
)
868 WriteConsoleOutputCharacters(Text
,
875 SetInputTextXY(SHORT x
, SHORT y
, SHORT len
, PWCHAR Text
)
884 Length
= wcslen(Text
);
885 if (Length
> len
- 1)
890 FillConsoleOutputAttribute(0x70,
895 WriteConsoleOutputCharactersW(Text
,
900 FillConsoleOutputCharacter('_',
905 if (len
> Length
+ 1)
908 FillConsoleOutputCharacter(' ',
917 SetUnderlinedTextXY(SHORT x
, SHORT y
, PCHAR Text
)
926 Length
= strlen(Text
);
928 WriteConsoleOutputCharacters(Text
,
933 FillConsoleOutputCharacter(0xCD,
941 SetInvertedTextXY(SHORT x
, SHORT y
, PCHAR Text
)
950 Length
= strlen(Text
);
952 FillConsoleOutputAttribute(0x71,
957 WriteConsoleOutputCharacters(Text
,
964 SetHighlightedTextXY(SHORT x
, SHORT y
, PCHAR Text
)
973 Length
= strlen(Text
);
975 FillConsoleOutputAttribute(0x1F,
980 WriteConsoleOutputCharacters(Text
,
987 PrintTextXY(SHORT x
, SHORT y
, char* fmt
, ...)
994 vsprintf(buffer
, fmt
, ap
);
1000 WriteConsoleOutputCharacters(buffer
,
1007 PrintTextXYN(SHORT x
, SHORT y
, SHORT len
, char* fmt
, ...)
1016 vsprintf(buffer
, fmt
, ap
);
1022 Length
= strlen(buffer
);
1023 if (Length
> len
- 1)
1028 WriteConsoleOutputCharacters(buffer
,
1036 FillConsoleOutputCharacter(' ',