update for HEAD-2002110401
[reactos.git] / subsys / system / usetup / console.c
1 /*
2  *  ReactOS kernel
3  *  Copyright (C) 2002 ReactOS Team
4  *
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.
9  *
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.
14  *
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.
18  */
19 /*
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
25  */
26
27 /* INCLUDES ******************************************************************/
28
29 #include <ddk/ntddk.h>
30 #include <ddk/ntddblue.h>
31
32 #include "usetup.h"
33 #include "console.h"
34
35
36 /* GLOBALS ******************************************************************/
37
38 static HANDLE StdInput  = INVALID_HANDLE_VALUE;
39 static HANDLE StdOutput = INVALID_HANDLE_VALUE;
40 static HANDLE InputEvent = INVALID_HANDLE_VALUE;
41
42 static SHORT xScreen = 0;
43 static SHORT yScreen = 0;
44
45
46 NTSTATUS
47 GetConsoleScreenBufferInfo(PCONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo);
48
49
50 /* FUNCTIONS *****************************************************************/
51
52
53
54 NTSTATUS
55 AllocConsole(VOID)
56 {
57   OBJECT_ATTRIBUTES ObjectAttributes;
58   IO_STATUS_BLOCK IoStatusBlock;
59   UNICODE_STRING Name;
60   NTSTATUS Status;
61   CONSOLE_SCREEN_BUFFER_INFO csbi;
62
63   /* Open the screen */
64   RtlInitUnicodeString(&Name,
65                        L"\\??\\BlueScreen");
66   InitializeObjectAttributes(&ObjectAttributes,
67                              &Name,
68                              0,
69                              NULL,
70                              NULL);
71   Status = NtCreateFile(&StdOutput,
72                         FILE_ALL_ACCESS,
73                         &ObjectAttributes,
74                         &IoStatusBlock,
75                         NULL,
76                         0,
77                         0,
78                         FILE_OPEN,
79                         0,
80                         NULL,
81                         0);
82   if (!NT_SUCCESS(Status))
83     return(Status);
84
85   /* Create input event */
86   Status = NtCreateEvent(&InputEvent,
87                          STANDARD_RIGHTS_ALL,
88                          NULL,
89                          FALSE,
90                          FALSE);
91   if (!NT_SUCCESS(Status))
92     return(Status);
93
94   /* Open the keyboard */
95   RtlInitUnicodeString(&Name,
96                        L"\\??\\Keyboard");
97   InitializeObjectAttributes(&ObjectAttributes,
98                              &Name,
99                              0,
100                              NULL,
101                              NULL);
102   Status = NtCreateFile(&StdInput,
103                         FILE_ALL_ACCESS,
104                         &ObjectAttributes,
105                         &IoStatusBlock,
106                         NULL,
107                         0,
108                         0,
109                         FILE_OPEN,
110                         0,
111                         NULL,
112                         0);
113
114   GetConsoleScreenBufferInfo(&csbi);
115
116   xScreen = csbi.dwSize.X;
117   yScreen = csbi.dwSize.Y;
118
119   return(Status);
120 }
121
122
123 VOID
124 FreeConsole(VOID)
125 {
126   if (StdInput != INVALID_HANDLE_VALUE)
127     NtClose(StdInput);
128
129   if (StdOutput != INVALID_HANDLE_VALUE)
130     NtClose(StdOutput);
131
132   if (InputEvent != INVALID_HANDLE_VALUE)
133     NtClose(InputEvent);
134 }
135
136
137
138
139 NTSTATUS
140 WriteConsole(PCHAR Buffer,
141              ULONG NumberOfCharsToWrite,
142              PULONG NumberOfCharsWritten)
143 {
144   IO_STATUS_BLOCK IoStatusBlock;
145   NTSTATUS Status = STATUS_SUCCESS;
146   ULONG i;
147
148   Status = NtWriteFile(StdOutput,
149                        NULL,
150                        NULL,
151                        NULL,
152                        &IoStatusBlock,
153                        Buffer,
154                        NumberOfCharsToWrite,
155                        NULL,
156                        NULL);
157   if (Status == STATUS_PENDING)
158     {
159       NtWaitForSingleObject(StdOutput,
160                             FALSE,
161                             NULL);
162       Status = IoStatusBlock.Status;
163     }
164
165   if (NumberOfCharsWritten != NULL)
166     {
167       *NumberOfCharsWritten = IoStatusBlock.Information;
168     }
169
170   return(Status);
171 }
172
173
174 #if 0
175 /*--------------------------------------------------------------
176  *      ReadConsoleA
177  */
178 WINBOOL
179 STDCALL
180 ReadConsoleA(HANDLE hConsoleInput,
181                              LPVOID lpBuffer,
182                              DWORD nNumberOfCharsToRead,
183                              LPDWORD lpNumberOfCharsRead,
184                              LPVOID lpReserved)
185 {
186   KEY_EVENT_RECORD KeyEventRecord;
187   BOOL  stat = TRUE;
188   PCHAR Buffer = (PCHAR)lpBuffer;
189   DWORD Result;
190   int   i;
191
192   for (i=0; (stat && i<nNumberOfCharsToRead);)
193     {
194       stat = ReadFile(hConsoleInput,
195                       &KeyEventRecord,
196                       sizeof(KEY_EVENT_RECORD),
197                       &Result,
198                       NULL);
199       if (stat && KeyEventRecord.bKeyDown && KeyEventRecord.uChar.AsciiChar != 0)
200         {
201           Buffer[i] = KeyEventRecord.uChar.AsciiChar;
202           i++;
203         }
204     }
205   if (lpNumberOfCharsRead != NULL)
206     {
207       *lpNumberOfCharsRead = i;
208     }
209   return(stat);
210 }
211 #endif
212
213
214 NTSTATUS
215 ReadConsoleInput(PINPUT_RECORD Buffer)
216 {
217   IO_STATUS_BLOCK Iosb;
218   NTSTATUS Status;
219
220   Buffer->EventType = KEY_EVENT;
221   Status = NtReadFile(StdInput,
222                       InputEvent,
223                       NULL,
224                       NULL,
225                       &Iosb,
226                       &Buffer->Event.KeyEvent,  //&KeyEventRecord->InputEvent.Event.KeyEvent,
227                       sizeof(KEY_EVENT_RECORD),
228                       NULL,
229                       0);
230
231       if( Status == STATUS_PENDING )
232         {
233           NtWaitForSingleObject(InputEvent,
234                                 FALSE,
235                                 NULL);
236           Status = Iosb.Status;
237         }
238
239   return(Status);
240 }
241
242
243 NTSTATUS
244 ReadConsoleOutputCharacters(LPSTR lpCharacter,
245                             ULONG nLength,
246                             COORD dwReadCoord,
247                             PULONG lpNumberOfCharsRead)
248 {
249   IO_STATUS_BLOCK IoStatusBlock;
250   ULONG dwBytesReturned;
251   OUTPUT_CHARACTER Buffer;
252   NTSTATUS Status;
253
254   Buffer.dwCoord    = dwReadCoord;
255
256   Status = NtDeviceIoControlFile(StdOutput,
257                                  NULL,
258                                  NULL,
259                                  NULL,
260                                  &IoStatusBlock,
261                                  IOCTL_CONSOLE_READ_OUTPUT_CHARACTER,
262                                  &Buffer,
263                                  sizeof(OUTPUT_CHARACTER),
264                                  (PVOID)lpCharacter,
265                                  nLength);
266   if (Status == STATUS_PENDING)
267     {
268       NtWaitForSingleObject(StdOutput,
269                             FALSE,
270                             NULL);
271       Status = IoStatusBlock.Status;
272     }
273
274   if (NT_SUCCESS(Status) && lpNumberOfCharsRead != NULL)
275     {
276       *lpNumberOfCharsRead = Buffer.dwTransfered;
277     }
278
279   return(Status);
280 }
281
282
283 NTSTATUS
284 ReadConsoleOutputAttributes(PUSHORT lpAttribute,
285                             ULONG nLength,
286                             COORD dwReadCoord,
287                             PULONG lpNumberOfAttrsRead)
288 {
289   IO_STATUS_BLOCK IoStatusBlock;
290   ULONG dwBytesReturned;
291   OUTPUT_ATTRIBUTE Buffer;
292   NTSTATUS Status;
293
294   Buffer.dwCoord = dwReadCoord;
295
296   Status = NtDeviceIoControlFile(StdOutput,
297                                  NULL,
298                                  NULL,
299                                  NULL,
300                                  &IoStatusBlock,
301                                  IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE,
302                                  &Buffer,
303                                  sizeof(OUTPUT_ATTRIBUTE),
304                                  (PVOID)lpAttribute,
305                                  nLength);
306   if (Status == STATUS_PENDING)
307     {
308       NtWaitForSingleObject(StdOutput,
309                             FALSE,
310                             NULL);
311       Status = IoStatusBlock.Status;
312     }
313
314   if (NT_SUCCESS(Status) && lpNumberOfAttrsRead != NULL)
315     {
316       *lpNumberOfAttrsRead = Buffer.dwTransfered;
317     }
318
319   return(Status);
320 }
321
322
323 NTSTATUS
324 WriteConsoleOutputCharacters(LPCSTR lpCharacter,
325                              ULONG nLength,
326                              COORD dwWriteCoord)
327 {
328   IO_STATUS_BLOCK IoStatusBlock;
329   PCHAR Buffer;
330   COORD *pCoord;
331   PCHAR pText;
332   NTSTATUS Status;
333
334   Buffer = RtlAllocateHeap(ProcessHeap,
335                            0,
336                            nLength + sizeof(COORD));
337   pCoord = (COORD *)Buffer;
338   pText = (PCHAR)(pCoord + 1);
339
340   *pCoord = dwWriteCoord;
341   memcpy(pText, lpCharacter, nLength);
342
343   Status = NtDeviceIoControlFile(StdOutput,
344                                  NULL,
345                                  NULL,
346                                  NULL,
347                                  &IoStatusBlock,
348                                  IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
349                                  NULL,
350                                  0,
351                                  Buffer,
352                                  nLength + sizeof(COORD));
353   if (Status == STATUS_PENDING)
354     {
355       NtWaitForSingleObject(StdOutput,
356                             FALSE,
357                             NULL);
358       Status = IoStatusBlock.Status;
359     }
360
361   RtlFreeHeap(ProcessHeap,
362               0,
363               Buffer);
364
365   return(Status);
366 }
367
368
369 NTSTATUS
370 WriteConsoleOutputAttributes(CONST USHORT *lpAttribute,
371                              ULONG nLength,
372                              COORD dwWriteCoord,
373                              PULONG lpNumberOfAttrsWritten)
374 {
375   IO_STATUS_BLOCK IoStatusBlock;
376   PUSHORT Buffer;
377   COORD *pCoord;
378   PUSHORT pAttrib;
379   NTSTATUS Status;
380
381   Buffer = RtlAllocateHeap(ProcessHeap,
382                            0,
383                            nLength * sizeof(USHORT) + sizeof(COORD));
384   pCoord = (COORD *)Buffer;
385   pAttrib = (PUSHORT)(pCoord + 1);
386
387   *pCoord = dwWriteCoord;
388   memcpy(pAttrib, lpAttribute, nLength * sizeof(USHORT));
389
390   Status = NtDeviceIoControlFile(StdOutput,
391                                  NULL,
392                                  NULL,
393                                  NULL,
394                                  &IoStatusBlock,
395                                  IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE,
396                                  NULL,
397                                  0,
398                                  Buffer,
399                                  nLength * sizeof(USHORT) + sizeof(COORD));
400   if (Status == STATUS_PENDING)
401     {
402       NtWaitForSingleObject(StdOutput,
403                             FALSE,
404                             NULL);
405       Status = IoStatusBlock.Status;
406     }
407
408   RtlFreeHeap(ProcessHeap,
409               0,
410               Buffer);
411
412   return(Status);
413 }
414
415
416 NTSTATUS
417 FillConsoleOutputAttribute(USHORT wAttribute,
418                            ULONG nLength,
419                            COORD dwWriteCoord,
420                            PULONG lpNumberOfAttrsWritten)
421 {
422   IO_STATUS_BLOCK IoStatusBlock;
423   OUTPUT_ATTRIBUTE Buffer;
424   ULONG dwBytesReturned;
425   NTSTATUS Status;
426
427   Buffer.wAttribute = wAttribute;
428   Buffer.nLength    = nLength;
429   Buffer.dwCoord    = dwWriteCoord;
430
431   Status = NtDeviceIoControlFile(StdOutput,
432                                  NULL,
433                                  NULL,
434                                  NULL,
435                                  &IoStatusBlock,
436                                  IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE,
437                                  &Buffer,
438                                  sizeof(OUTPUT_ATTRIBUTE),
439                                  &Buffer,
440                                  sizeof(OUTPUT_ATTRIBUTE));
441   if (Status == STATUS_PENDING)
442     {
443       NtWaitForSingleObject(StdOutput,
444                             FALSE,
445                             NULL);
446       Status = IoStatusBlock.Status;
447     }
448   if (NT_SUCCESS(Status))
449     {
450       *lpNumberOfAttrsWritten = Buffer.dwTransfered;
451     }
452
453   return(Status);
454 }
455
456
457 NTSTATUS
458 FillConsoleOutputCharacter(CHAR Character,
459                            ULONG Length,
460                            COORD WriteCoord,
461                            PULONG NumberOfCharsWritten)
462 {
463   IO_STATUS_BLOCK IoStatusBlock;
464   OUTPUT_CHARACTER Buffer;
465   ULONG dwBytesReturned;
466   NTSTATUS Status;
467
468   Buffer.cCharacter = Character;
469   Buffer.nLength = Length;
470   Buffer.dwCoord = WriteCoord;
471
472   Status = NtDeviceIoControlFile(StdOutput,
473                                  NULL,
474                                  NULL,
475                                  NULL,
476                                  &IoStatusBlock,
477                                  IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER,
478                                  &Buffer,
479                                  sizeof(OUTPUT_CHARACTER),
480                                  &Buffer,
481                                  sizeof(OUTPUT_CHARACTER));
482   if (Status == STATUS_PENDING)
483     {
484       NtWaitForSingleObject(StdOutput,
485                             FALSE,
486                             NULL);
487       Status = IoStatusBlock.Status;
488     }
489   if (NT_SUCCESS(Status))
490     {
491       *NumberOfCharsWritten = Buffer.dwTransfered;
492     }
493
494   return(Status);
495 }
496
497
498 #if 0
499 /*--------------------------------------------------------------
500  *      GetConsoleMode
501  */
502 WINBASEAPI
503 BOOL
504 WINAPI
505 GetConsoleMode(
506         HANDLE          hConsoleHandle,
507         LPDWORD         lpMode
508         )
509 {
510     CONSOLE_MODE Buffer;
511     DWORD   dwBytesReturned;
512         
513     if (DeviceIoControl (hConsoleHandle,
514                          IOCTL_CONSOLE_GET_MODE,
515                          NULL,
516                          0,
517                          &Buffer,
518                          sizeof(CONSOLE_MODE),
519                          &dwBytesReturned,
520                          NULL))
521     {
522         *lpMode = Buffer.dwMode;
523         SetLastError (ERROR_SUCCESS);
524         return TRUE;
525     }
526
527     SetLastError(0); /* FIXME: What error code? */
528     return FALSE;
529 }
530
531
532 /*--------------------------------------------------------------
533  *      GetConsoleCursorInfo
534  */
535 WINBASEAPI
536 BOOL
537 WINAPI
538 GetConsoleCursorInfo(
539         HANDLE                  hConsoleOutput,
540         PCONSOLE_CURSOR_INFO    lpConsoleCursorInfo
541         )
542 {
543     DWORD   dwBytesReturned;
544         
545     if (DeviceIoControl (hConsoleOutput,
546                          IOCTL_CONSOLE_GET_CURSOR_INFO,
547                          NULL,
548                          0,
549                          lpConsoleCursorInfo,
550                          sizeof(CONSOLE_CURSOR_INFO),
551                          &dwBytesReturned,
552                          NULL))
553         return TRUE;
554
555     return FALSE;
556 }
557
558
559 NTSTATUS
560 SetConsoleMode(HANDLE hConsoleHandle,
561                ULONG dwMode)
562 {
563   IO_STATUS_BLOCK IoStatusBlock;
564   NTSTATUS Status;
565   CONSOLE_MODE Buffer;
566
567   Buffer.dwMode = dwMode;
568
569   Status = NtDeviceIoControlFile(hConsoleHandle,
570                                  NULL,
571                                  NULL,
572                                  NULL,
573                                  &IoStatusBlock,
574                                  IOCTL_CONSOLE_SET_MODE,
575                                  &Buffer,
576                                  sizeof(CONSOLE_MODE),
577                                  NULL,
578                                  0);
579   if (Status == STATUS_PENDING)
580     {
581       NtWaitForSingleObject(hConsoleHandle,
582                             FALSE,
583                             NULL);
584       Status = IoStatusBlock.Status;
585     }
586   return(Status);
587 }
588 #endif
589
590
591 NTSTATUS
592 GetConsoleScreenBufferInfo(PCONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo)
593 {
594   IO_STATUS_BLOCK IoStatusBlock;
595   NTSTATUS Status;
596
597   Status = NtDeviceIoControlFile(StdOutput,
598                                  NULL,
599                                  NULL,
600                                  NULL,
601                                  &IoStatusBlock,
602                                  IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
603                                  NULL,
604                                  0,
605                                  ConsoleScreenBufferInfo,
606                                  sizeof(CONSOLE_SCREEN_BUFFER_INFO));
607   if (Status == STATUS_PENDING)
608     {
609       NtWaitForSingleObject(StdOutput,
610                             FALSE,
611                             NULL);
612       Status = IoStatusBlock.Status;
613     }
614
615   return(Status);
616 }
617
618
619 NTSTATUS
620 SetConsoleCursorInfo(PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
621 {
622   IO_STATUS_BLOCK IoStatusBlock;
623   NTSTATUS Status;
624
625   Status = NtDeviceIoControlFile(StdOutput,
626                                  NULL,
627                                  NULL,
628                                  NULL,
629                                  &IoStatusBlock,
630                                  IOCTL_CONSOLE_SET_CURSOR_INFO,
631                                  (PCONSOLE_CURSOR_INFO)lpConsoleCursorInfo,
632                                  sizeof(CONSOLE_CURSOR_INFO),
633                                  NULL,
634                                  0);
635   if (Status == STATUS_PENDING)
636     {
637       NtWaitForSingleObject(StdOutput,
638                             FALSE,
639                             NULL);
640       Status = IoStatusBlock.Status;
641     }
642   return(Status);
643 }
644
645
646 NTSTATUS
647 SetConsoleCursorPosition(COORD dwCursorPosition)
648 {
649   CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
650   IO_STATUS_BLOCK IoStatusBlock;
651   NTSTATUS Status;
652
653   Status = GetConsoleScreenBufferInfo(&ConsoleScreenBufferInfo);
654   if (!NT_SUCCESS(Status))
655     return(Status);
656
657   ConsoleScreenBufferInfo.dwCursorPosition.X = dwCursorPosition.X;
658   ConsoleScreenBufferInfo.dwCursorPosition.Y = dwCursorPosition.Y;
659
660   Status = NtDeviceIoControlFile(StdOutput,
661                                  NULL,
662                                  NULL,
663                                  NULL,
664                                  &IoStatusBlock,
665                                  IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
666                                  &ConsoleScreenBufferInfo,
667                                  sizeof(CONSOLE_SCREEN_BUFFER_INFO),
668                                  NULL,
669                                  0);
670   if (Status == STATUS_PENDING)
671     {
672       NtWaitForSingleObject(StdOutput,
673                             FALSE,
674                             NULL);
675       Status = IoStatusBlock.Status;
676     }
677   return(Status);
678 }
679
680
681 NTSTATUS
682 SetConsoleTextAttribute(WORD wAttributes)
683 {
684   IO_STATUS_BLOCK IoStatusBlock;
685   NTSTATUS Status;
686
687   Status = NtDeviceIoControlFile(StdOutput,
688                                  NULL,
689                                  NULL,
690                                  NULL,
691                                  &IoStatusBlock,
692                                  IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE,
693                                  &wAttributes,
694                                  sizeof(WORD),
695                                  NULL,
696                                  0);
697   if (Status == STATUS_PENDING)
698     {
699       NtWaitForSingleObject(StdOutput,
700                             FALSE,
701                             NULL);
702       Status = IoStatusBlock.Status;
703     }
704   return(Status);
705 }
706
707
708
709
710 VOID
711 ConInKey(PINPUT_RECORD Buffer)
712 {
713   ULONG KeysRead;
714
715   while (TRUE)
716     {
717       ReadConsoleInput(Buffer);
718
719       if ((Buffer->EventType == KEY_EVENT) &&
720           (Buffer->Event.KeyEvent.bKeyDown == TRUE))
721           break;
722     }
723 }
724
725
726 VOID
727 ConOutChar(CHAR c)
728 {
729   ULONG Written;
730
731   WriteConsole(&c,
732                1,
733                &Written);
734 }
735
736
737 VOID
738 ConOutPuts(LPSTR szText)
739 {
740   ULONG Written;
741
742   WriteConsole(szText,
743                strlen(szText),
744                &Written);
745   WriteConsole("\n",
746                1,
747                &Written);
748 }
749
750
751 VOID
752 ConOutPrintf(LPSTR szFormat, ...)
753 {
754   CHAR szOut[256];
755   DWORD dwWritten;
756   va_list arg_ptr;
757
758   va_start(arg_ptr, szFormat);
759   vsprintf(szOut, szFormat, arg_ptr);
760   va_end(arg_ptr);
761
762   WriteConsole(szOut,
763                strlen(szOut),
764                &dwWritten);
765 }
766
767
768
769
770
771 SHORT
772 GetCursorX(VOID)
773 {
774   CONSOLE_SCREEN_BUFFER_INFO csbi;
775
776   GetConsoleScreenBufferInfo(&csbi);
777
778   return(csbi.dwCursorPosition.X);
779 }
780
781
782 SHORT
783 GetCursorY(VOID)
784 {
785   CONSOLE_SCREEN_BUFFER_INFO csbi;
786
787   GetConsoleScreenBufferInfo(&csbi);
788
789   return(csbi.dwCursorPosition.Y);
790 }
791
792
793 VOID
794 GetScreenSize(SHORT *maxx,
795               SHORT *maxy)
796 {
797   CONSOLE_SCREEN_BUFFER_INFO csbi;
798
799   GetConsoleScreenBufferInfo(&csbi);
800
801   if (maxx)
802     *maxx = csbi.dwSize.X;
803
804   if (maxy)
805     *maxy = csbi.dwSize.Y;
806 }
807
808
809 VOID
810 SetCursorType(BOOL bInsert,
811               BOOL bVisible)
812 {
813   CONSOLE_CURSOR_INFO cci;
814
815   cci.dwSize = bInsert ? 10 : 99;
816   cci.bVisible = bVisible;
817
818   SetConsoleCursorInfo(&cci);
819 }
820
821
822 VOID
823 SetCursorXY(SHORT x,
824             SHORT y)
825 {
826   COORD coPos;
827
828   coPos.X = x;
829   coPos.Y = y;
830   SetConsoleCursorPosition(coPos);
831 }
832
833
834 VOID
835 ClearScreen(VOID)
836 {
837   COORD coPos;
838   ULONG Written;
839
840   coPos.X = 0;
841   coPos.Y = 0;
842
843   FillConsoleOutputAttribute(0x17,
844                              xScreen * yScreen,
845                              coPos,
846                              &Written);
847
848   FillConsoleOutputCharacter(' ',
849                              xScreen * yScreen,
850                              coPos,
851                              &Written);
852 }
853
854
855 VOID
856 SetStatusText(PCHAR Text)
857 {
858   COORD coPos;
859   ULONG Written;
860
861   coPos.X = 0;
862   coPos.Y = yScreen - 1;
863
864   FillConsoleOutputAttribute(0x70,
865                              xScreen,
866                              coPos,
867                              &Written);
868
869   FillConsoleOutputCharacter(' ',
870                              xScreen,
871                              coPos,
872                              &Written);
873
874   WriteConsoleOutputCharacters(Text,
875                                strlen(Text),
876                                coPos);
877 }
878
879
880 VOID
881 SetTextXY(SHORT x, SHORT y, PCHAR Text)
882 {
883   COORD coPos;
884
885   coPos.X = x;
886   coPos.Y = y;
887
888   WriteConsoleOutputCharacters(Text,
889                                strlen(Text),
890                                coPos);
891 }
892
893
894 VOID
895 SetInputTextXY(SHORT x, SHORT y, SHORT len, PCHAR Text)
896 {
897   COORD coPos;
898   ULONG Length;
899   ULONG Written;
900
901   coPos.X = x;
902   coPos.Y = y;
903
904   Length = strlen(Text);
905
906   FillConsoleOutputAttribute(0x70,
907                              len,
908                              coPos,
909                              &Written);
910
911   WriteConsoleOutputCharacters(Text,
912                                Length,
913                                coPos);
914
915   coPos.X += Length;
916   FillConsoleOutputCharacter('_',
917                              1,
918                              coPos,
919                              &Written);
920
921   if (len > Length + 1)
922     {
923       coPos.X++;
924       FillConsoleOutputCharacter(' ',
925                                  len - Length - 1,
926                                  coPos,
927                                  &Written);
928     }
929 }
930
931
932 VOID
933 SetUnderlinedTextXY(SHORT x, SHORT y, PCHAR Text)
934 {
935   COORD coPos;
936   ULONG Length;
937   ULONG Written;
938
939   coPos.X = x;
940   coPos.Y = y;
941
942   Length = strlen(Text);
943
944   WriteConsoleOutputCharacters(Text,
945                                Length,
946                                coPos);
947
948   coPos.Y++;
949   FillConsoleOutputCharacter(0xCD,
950                              Length,
951                              coPos,
952                              &Written);
953 }
954
955
956 VOID
957 SetInvertedTextXY(SHORT x, SHORT y, PCHAR Text)
958 {
959   COORD coPos;
960   ULONG Length;
961   ULONG Written;
962
963   coPos.X = x;
964   coPos.Y = y;
965
966   Length = strlen(Text);
967
968   FillConsoleOutputAttribute(0x71,
969                              Length,
970                              coPos,
971                              &Written);
972
973   WriteConsoleOutputCharacters(Text,
974                                Length,
975                                coPos);
976 }
977
978
979 VOID
980 SetHighlightedTextXY(SHORT x, SHORT y, PCHAR Text)
981 {
982   COORD coPos;
983   ULONG Length;
984   ULONG Written;
985
986   coPos.X = x;
987   coPos.Y = y;
988
989   Length = strlen(Text);
990
991   FillConsoleOutputAttribute(0x1F,
992                              Length,
993                              coPos,
994                              &Written);
995
996   WriteConsoleOutputCharacters(Text,
997                                Length,
998                                coPos);
999 }
1000
1001
1002 VOID
1003 PrintTextXY(SHORT x, SHORT y, char* fmt,...)
1004 {
1005   char buffer[512];
1006   va_list ap;
1007   COORD coPos;
1008
1009   va_start(ap, fmt);
1010   vsprintf(buffer, fmt, ap);
1011   va_end(ap);
1012
1013   coPos.X = x;
1014   coPos.Y = y;
1015
1016   WriteConsoleOutputCharacters(buffer,
1017                                strlen(buffer),
1018                                coPos);
1019 }
1020
1021 /* EOF */