branch update for HEAD-2003021201
[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 WriteConsoleOutputCharactersW(LPCWSTR lpCharacter,
371                               ULONG nLength,
372                               COORD dwWriteCoord)
373 {
374   IO_STATUS_BLOCK IoStatusBlock;
375   PCHAR Buffer;
376   COORD *pCoord;
377   PCHAR pText;
378   NTSTATUS Status;
379   ULONG i;
380
381   Buffer = RtlAllocateHeap(ProcessHeap,
382                            0,
383                            nLength + sizeof(COORD));
384   pCoord = (COORD *)Buffer;
385   pText = (PCHAR)(pCoord + 1);
386
387   *pCoord = dwWriteCoord;
388
389   /* FIXME: use real unicode->oem conversion */
390   for (i = 0; i < nLength; i++)
391     pText[i] = (CHAR)lpCharacter[i];
392   pText[i] = 0;
393
394   Status = NtDeviceIoControlFile(StdOutput,
395                                  NULL,
396                                  NULL,
397                                  NULL,
398                                  &IoStatusBlock,
399                                  IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
400                                  NULL,
401                                  0,
402                                  Buffer,
403                                  nLength + sizeof(COORD));
404   if (Status == STATUS_PENDING)
405     {
406       NtWaitForSingleObject(StdOutput,
407                             FALSE,
408                             NULL);
409       Status = IoStatusBlock.Status;
410     }
411
412   RtlFreeHeap(ProcessHeap,
413               0,
414               Buffer);
415
416   return(Status);
417 }
418
419
420 NTSTATUS
421 WriteConsoleOutputAttributes(CONST USHORT *lpAttribute,
422                              ULONG nLength,
423                              COORD dwWriteCoord,
424                              PULONG lpNumberOfAttrsWritten)
425 {
426   IO_STATUS_BLOCK IoStatusBlock;
427   PUSHORT Buffer;
428   COORD *pCoord;
429   PUSHORT pAttrib;
430   NTSTATUS Status;
431
432   Buffer = RtlAllocateHeap(ProcessHeap,
433                            0,
434                            nLength * sizeof(USHORT) + sizeof(COORD));
435   pCoord = (COORD *)Buffer;
436   pAttrib = (PUSHORT)(pCoord + 1);
437
438   *pCoord = dwWriteCoord;
439   memcpy(pAttrib, lpAttribute, nLength * sizeof(USHORT));
440
441   Status = NtDeviceIoControlFile(StdOutput,
442                                  NULL,
443                                  NULL,
444                                  NULL,
445                                  &IoStatusBlock,
446                                  IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE,
447                                  NULL,
448                                  0,
449                                  Buffer,
450                                  nLength * sizeof(USHORT) + sizeof(COORD));
451   if (Status == STATUS_PENDING)
452     {
453       NtWaitForSingleObject(StdOutput,
454                             FALSE,
455                             NULL);
456       Status = IoStatusBlock.Status;
457     }
458
459   RtlFreeHeap(ProcessHeap,
460               0,
461               Buffer);
462
463   return(Status);
464 }
465
466
467 NTSTATUS
468 FillConsoleOutputAttribute(USHORT wAttribute,
469                            ULONG nLength,
470                            COORD dwWriteCoord,
471                            PULONG lpNumberOfAttrsWritten)
472 {
473   IO_STATUS_BLOCK IoStatusBlock;
474   OUTPUT_ATTRIBUTE Buffer;
475   ULONG dwBytesReturned;
476   NTSTATUS Status;
477
478   Buffer.wAttribute = wAttribute;
479   Buffer.nLength    = nLength;
480   Buffer.dwCoord    = dwWriteCoord;
481
482   Status = NtDeviceIoControlFile(StdOutput,
483                                  NULL,
484                                  NULL,
485                                  NULL,
486                                  &IoStatusBlock,
487                                  IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE,
488                                  &Buffer,
489                                  sizeof(OUTPUT_ATTRIBUTE),
490                                  &Buffer,
491                                  sizeof(OUTPUT_ATTRIBUTE));
492   if (Status == STATUS_PENDING)
493     {
494       NtWaitForSingleObject(StdOutput,
495                             FALSE,
496                             NULL);
497       Status = IoStatusBlock.Status;
498     }
499   if (NT_SUCCESS(Status))
500     {
501       *lpNumberOfAttrsWritten = Buffer.dwTransfered;
502     }
503
504   return(Status);
505 }
506
507
508 NTSTATUS
509 FillConsoleOutputCharacter(CHAR Character,
510                            ULONG Length,
511                            COORD WriteCoord,
512                            PULONG NumberOfCharsWritten)
513 {
514   IO_STATUS_BLOCK IoStatusBlock;
515   OUTPUT_CHARACTER Buffer;
516   ULONG dwBytesReturned;
517   NTSTATUS Status;
518
519   Buffer.cCharacter = Character;
520   Buffer.nLength = Length;
521   Buffer.dwCoord = WriteCoord;
522
523   Status = NtDeviceIoControlFile(StdOutput,
524                                  NULL,
525                                  NULL,
526                                  NULL,
527                                  &IoStatusBlock,
528                                  IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER,
529                                  &Buffer,
530                                  sizeof(OUTPUT_CHARACTER),
531                                  &Buffer,
532                                  sizeof(OUTPUT_CHARACTER));
533   if (Status == STATUS_PENDING)
534     {
535       NtWaitForSingleObject(StdOutput,
536                             FALSE,
537                             NULL);
538       Status = IoStatusBlock.Status;
539     }
540   if (NT_SUCCESS(Status))
541     {
542       *NumberOfCharsWritten = Buffer.dwTransfered;
543     }
544
545   return(Status);
546 }
547
548
549 #if 0
550 /*--------------------------------------------------------------
551  *      GetConsoleMode
552  */
553 WINBASEAPI
554 BOOL
555 WINAPI
556 GetConsoleMode(
557         HANDLE          hConsoleHandle,
558         LPDWORD         lpMode
559         )
560 {
561     CONSOLE_MODE Buffer;
562     DWORD   dwBytesReturned;
563         
564     if (DeviceIoControl (hConsoleHandle,
565                          IOCTL_CONSOLE_GET_MODE,
566                          NULL,
567                          0,
568                          &Buffer,
569                          sizeof(CONSOLE_MODE),
570                          &dwBytesReturned,
571                          NULL))
572     {
573         *lpMode = Buffer.dwMode;
574         SetLastError (ERROR_SUCCESS);
575         return TRUE;
576     }
577
578     SetLastError(0); /* FIXME: What error code? */
579     return FALSE;
580 }
581
582
583 /*--------------------------------------------------------------
584  *      GetConsoleCursorInfo
585  */
586 WINBASEAPI
587 BOOL
588 WINAPI
589 GetConsoleCursorInfo(
590         HANDLE                  hConsoleOutput,
591         PCONSOLE_CURSOR_INFO    lpConsoleCursorInfo
592         )
593 {
594     DWORD   dwBytesReturned;
595         
596     if (DeviceIoControl (hConsoleOutput,
597                          IOCTL_CONSOLE_GET_CURSOR_INFO,
598                          NULL,
599                          0,
600                          lpConsoleCursorInfo,
601                          sizeof(CONSOLE_CURSOR_INFO),
602                          &dwBytesReturned,
603                          NULL))
604         return TRUE;
605
606     return FALSE;
607 }
608
609
610 NTSTATUS
611 SetConsoleMode(HANDLE hConsoleHandle,
612                ULONG dwMode)
613 {
614   IO_STATUS_BLOCK IoStatusBlock;
615   NTSTATUS Status;
616   CONSOLE_MODE Buffer;
617
618   Buffer.dwMode = dwMode;
619
620   Status = NtDeviceIoControlFile(hConsoleHandle,
621                                  NULL,
622                                  NULL,
623                                  NULL,
624                                  &IoStatusBlock,
625                                  IOCTL_CONSOLE_SET_MODE,
626                                  &Buffer,
627                                  sizeof(CONSOLE_MODE),
628                                  NULL,
629                                  0);
630   if (Status == STATUS_PENDING)
631     {
632       NtWaitForSingleObject(hConsoleHandle,
633                             FALSE,
634                             NULL);
635       Status = IoStatusBlock.Status;
636     }
637   return(Status);
638 }
639 #endif
640
641
642 NTSTATUS
643 GetConsoleScreenBufferInfo(PCONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo)
644 {
645   IO_STATUS_BLOCK IoStatusBlock;
646   NTSTATUS Status;
647
648   Status = NtDeviceIoControlFile(StdOutput,
649                                  NULL,
650                                  NULL,
651                                  NULL,
652                                  &IoStatusBlock,
653                                  IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
654                                  NULL,
655                                  0,
656                                  ConsoleScreenBufferInfo,
657                                  sizeof(CONSOLE_SCREEN_BUFFER_INFO));
658   if (Status == STATUS_PENDING)
659     {
660       NtWaitForSingleObject(StdOutput,
661                             FALSE,
662                             NULL);
663       Status = IoStatusBlock.Status;
664     }
665
666   return(Status);
667 }
668
669
670 NTSTATUS
671 SetConsoleCursorInfo(PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
672 {
673   IO_STATUS_BLOCK IoStatusBlock;
674   NTSTATUS Status;
675
676   Status = NtDeviceIoControlFile(StdOutput,
677                                  NULL,
678                                  NULL,
679                                  NULL,
680                                  &IoStatusBlock,
681                                  IOCTL_CONSOLE_SET_CURSOR_INFO,
682                                  (PCONSOLE_CURSOR_INFO)lpConsoleCursorInfo,
683                                  sizeof(CONSOLE_CURSOR_INFO),
684                                  NULL,
685                                  0);
686   if (Status == STATUS_PENDING)
687     {
688       NtWaitForSingleObject(StdOutput,
689                             FALSE,
690                             NULL);
691       Status = IoStatusBlock.Status;
692     }
693   return(Status);
694 }
695
696
697 NTSTATUS
698 SetConsoleCursorPosition(COORD dwCursorPosition)
699 {
700   CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
701   IO_STATUS_BLOCK IoStatusBlock;
702   NTSTATUS Status;
703
704   Status = GetConsoleScreenBufferInfo(&ConsoleScreenBufferInfo);
705   if (!NT_SUCCESS(Status))
706     return(Status);
707
708   ConsoleScreenBufferInfo.dwCursorPosition.X = dwCursorPosition.X;
709   ConsoleScreenBufferInfo.dwCursorPosition.Y = dwCursorPosition.Y;
710
711   Status = NtDeviceIoControlFile(StdOutput,
712                                  NULL,
713                                  NULL,
714                                  NULL,
715                                  &IoStatusBlock,
716                                  IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
717                                  &ConsoleScreenBufferInfo,
718                                  sizeof(CONSOLE_SCREEN_BUFFER_INFO),
719                                  NULL,
720                                  0);
721   if (Status == STATUS_PENDING)
722     {
723       NtWaitForSingleObject(StdOutput,
724                             FALSE,
725                             NULL);
726       Status = IoStatusBlock.Status;
727     }
728   return(Status);
729 }
730
731
732 NTSTATUS
733 SetConsoleTextAttribute(WORD wAttributes)
734 {
735   IO_STATUS_BLOCK IoStatusBlock;
736   NTSTATUS Status;
737
738   Status = NtDeviceIoControlFile(StdOutput,
739                                  NULL,
740                                  NULL,
741                                  NULL,
742                                  &IoStatusBlock,
743                                  IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE,
744                                  &wAttributes,
745                                  sizeof(WORD),
746                                  NULL,
747                                  0);
748   if (Status == STATUS_PENDING)
749     {
750       NtWaitForSingleObject(StdOutput,
751                             FALSE,
752                             NULL);
753       Status = IoStatusBlock.Status;
754     }
755   return(Status);
756 }
757
758
759
760
761 VOID
762 ConInKey(PINPUT_RECORD Buffer)
763 {
764   ULONG KeysRead;
765
766   while (TRUE)
767     {
768       ReadConsoleInput(Buffer);
769
770       if ((Buffer->EventType == KEY_EVENT) &&
771           (Buffer->Event.KeyEvent.bKeyDown == TRUE))
772           break;
773     }
774 }
775
776
777 VOID
778 ConOutChar(CHAR c)
779 {
780   ULONG Written;
781
782   WriteConsole(&c,
783                1,
784                &Written);
785 }
786
787
788 VOID
789 ConOutPuts(LPSTR szText)
790 {
791   ULONG Written;
792
793   WriteConsole(szText,
794                strlen(szText),
795                &Written);
796   WriteConsole("\n",
797                1,
798                &Written);
799 }
800
801
802 VOID
803 ConOutPrintf(LPSTR szFormat, ...)
804 {
805   CHAR szOut[256];
806   DWORD dwWritten;
807   va_list arg_ptr;
808
809   va_start(arg_ptr, szFormat);
810   vsprintf(szOut, szFormat, arg_ptr);
811   va_end(arg_ptr);
812
813   WriteConsole(szOut,
814                strlen(szOut),
815                &dwWritten);
816 }
817
818
819
820
821
822 SHORT
823 GetCursorX(VOID)
824 {
825   CONSOLE_SCREEN_BUFFER_INFO csbi;
826
827   GetConsoleScreenBufferInfo(&csbi);
828
829   return(csbi.dwCursorPosition.X);
830 }
831
832
833 SHORT
834 GetCursorY(VOID)
835 {
836   CONSOLE_SCREEN_BUFFER_INFO csbi;
837
838   GetConsoleScreenBufferInfo(&csbi);
839
840   return(csbi.dwCursorPosition.Y);
841 }
842
843
844 VOID
845 GetScreenSize(SHORT *maxx,
846               SHORT *maxy)
847 {
848   CONSOLE_SCREEN_BUFFER_INFO csbi;
849
850   GetConsoleScreenBufferInfo(&csbi);
851
852   if (maxx)
853     *maxx = csbi.dwSize.X;
854
855   if (maxy)
856     *maxy = csbi.dwSize.Y;
857 }
858
859
860 VOID
861 SetCursorType(BOOL bInsert,
862               BOOL bVisible)
863 {
864   CONSOLE_CURSOR_INFO cci;
865
866   cci.dwSize = bInsert ? 10 : 99;
867   cci.bVisible = bVisible;
868
869   SetConsoleCursorInfo(&cci);
870 }
871
872
873 VOID
874 SetCursorXY(SHORT x,
875             SHORT y)
876 {
877   COORD coPos;
878
879   coPos.X = x;
880   coPos.Y = y;
881   SetConsoleCursorPosition(coPos);
882 }
883
884
885 VOID
886 ClearScreen(VOID)
887 {
888   COORD coPos;
889   ULONG Written;
890
891   coPos.X = 0;
892   coPos.Y = 0;
893
894   FillConsoleOutputAttribute(0x17,
895                              xScreen * yScreen,
896                              coPos,
897                              &Written);
898
899   FillConsoleOutputCharacter(' ',
900                              xScreen * yScreen,
901                              coPos,
902                              &Written);
903 }
904
905
906 VOID
907 SetStatusText(PCHAR Text)
908 {
909   COORD coPos;
910   ULONG Written;
911
912   coPos.X = 0;
913   coPos.Y = yScreen - 1;
914
915   FillConsoleOutputAttribute(0x70,
916                              xScreen,
917                              coPos,
918                              &Written);
919
920   FillConsoleOutputCharacter(' ',
921                              xScreen,
922                              coPos,
923                              &Written);
924
925   WriteConsoleOutputCharacters(Text,
926                                strlen(Text),
927                                coPos);
928 }
929
930
931 VOID
932 SetTextXY(SHORT x, SHORT y, PCHAR Text)
933 {
934   COORD coPos;
935
936   coPos.X = x;
937   coPos.Y = y;
938
939   WriteConsoleOutputCharacters(Text,
940                                strlen(Text),
941                                coPos);
942 }
943
944
945 VOID
946 SetInputTextXY(SHORT x, SHORT y, SHORT len, PWCHAR Text)
947 {
948   COORD coPos;
949   ULONG Length;
950   ULONG Written;
951
952   coPos.X = x;
953   coPos.Y = y;
954
955   Length = wcslen(Text);
956   if (Length > len - 1)
957     {
958       Length = len - 1;
959     }
960
961   FillConsoleOutputAttribute(0x70,
962                              len,
963                              coPos,
964                              &Written);
965
966   WriteConsoleOutputCharactersW(Text,
967                                 Length,
968                                 coPos);
969
970   coPos.X += Length;
971   FillConsoleOutputCharacter('_',
972                              1,
973                              coPos,
974                              &Written);
975
976   if (len > Length + 1)
977     {
978       coPos.X++;
979       FillConsoleOutputCharacter(' ',
980                                  len - Length - 1,
981                                  coPos,
982                                  &Written);
983     }
984 }
985
986
987 VOID
988 SetUnderlinedTextXY(SHORT x, SHORT y, PCHAR Text)
989 {
990   COORD coPos;
991   ULONG Length;
992   ULONG Written;
993
994   coPos.X = x;
995   coPos.Y = y;
996
997   Length = strlen(Text);
998
999   WriteConsoleOutputCharacters(Text,
1000                                Length,
1001                                coPos);
1002
1003   coPos.Y++;
1004   FillConsoleOutputCharacter(0xCD,
1005                              Length,
1006                              coPos,
1007                              &Written);
1008 }
1009
1010
1011 VOID
1012 SetInvertedTextXY(SHORT x, SHORT y, PCHAR Text)
1013 {
1014   COORD coPos;
1015   ULONG Length;
1016   ULONG Written;
1017
1018   coPos.X = x;
1019   coPos.Y = y;
1020
1021   Length = strlen(Text);
1022
1023   FillConsoleOutputAttribute(0x71,
1024                              Length,
1025                              coPos,
1026                              &Written);
1027
1028   WriteConsoleOutputCharacters(Text,
1029                                Length,
1030                                coPos);
1031 }
1032
1033
1034 VOID
1035 SetHighlightedTextXY(SHORT x, SHORT y, PCHAR Text)
1036 {
1037   COORD coPos;
1038   ULONG Length;
1039   ULONG Written;
1040
1041   coPos.X = x;
1042   coPos.Y = y;
1043
1044   Length = strlen(Text);
1045
1046   FillConsoleOutputAttribute(0x1F,
1047                              Length,
1048                              coPos,
1049                              &Written);
1050
1051   WriteConsoleOutputCharacters(Text,
1052                                Length,
1053                                coPos);
1054 }
1055
1056
1057 VOID
1058 PrintTextXY(SHORT x, SHORT y, char* fmt, ...)
1059 {
1060   char buffer[512];
1061   va_list ap;
1062   COORD coPos;
1063
1064   va_start(ap, fmt);
1065   vsprintf(buffer, fmt, ap);
1066   va_end(ap);
1067
1068   coPos.X = x;
1069   coPos.Y = y;
1070
1071   WriteConsoleOutputCharacters(buffer,
1072                                strlen(buffer),
1073                                coPos);
1074 }
1075
1076
1077 VOID
1078 PrintTextXYN(SHORT x, SHORT y, SHORT len, char* fmt, ...)
1079 {
1080   char buffer[512];
1081   va_list ap;
1082   COORD coPos;
1083   ULONG Length;
1084   ULONG Written;
1085
1086   va_start(ap, fmt);
1087   vsprintf(buffer, fmt, ap);
1088   va_end(ap);
1089
1090   coPos.X = x;
1091   coPos.Y = y;
1092
1093   Length = strlen(buffer);
1094   if (Length > len - 1)
1095     {
1096       Length = len - 1;
1097     }
1098
1099   WriteConsoleOutputCharacters(buffer,
1100                                Length,
1101                                coPos);
1102
1103   coPos.X += Length;
1104
1105   if (len > Length)
1106     {
1107       FillConsoleOutputCharacter(' ',
1108                                  len - Length,
1109                                  coPos,
1110                                  &Written);
1111     }
1112 }
1113
1114
1115 /* EOF */