xref: /reactos/base/setup/usetup/consup.c (revision cc7cf826)
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 along
16  *  with this program; if not, write to the Free Software Foundation, Inc.,
17  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 /*
20  * COPYRIGHT:       See COPYING in the top level directory
21  * PROJECT:         ReactOS text-mode setup
22  * FILE:            base/setup/usetup/consup.c
23  * PURPOSE:         Console support functions
24  * PROGRAMMER:
25  */
26 
27 /* INCLUDES ******************************************************************/
28 
29 #include <usetup.h>
30 
31 #define NDEBUG
32 #include <debug.h>
33 
34 /* GLOBALS ******************************************************************/
35 
36 HANDLE StdInput  = INVALID_HANDLE_VALUE;
37 HANDLE StdOutput = INVALID_HANDLE_VALUE;
38 
39 SHORT xScreen = 0;
40 SHORT yScreen = 0;
41 
42 /* FUNCTIONS *****************************************************************/
43 
44 BOOLEAN
45 CONSOLE_Init(
46     VOID)
47 {
48     CONSOLE_SCREEN_BUFFER_INFO csbi;
49     if (!AllocConsole())
50         return FALSE;
51 
52     StdInput = GetStdHandle(STD_INPUT_HANDLE);
53     StdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
54     if (!GetConsoleScreenBufferInfo(StdOutput, &csbi))
55         return FALSE;
56     xScreen = csbi.dwSize.X;
57     yScreen = csbi.dwSize.Y;
58     return TRUE;
59 }
60 
61 VOID
62 CONSOLE_ConInKey(
63     OUT PINPUT_RECORD Buffer)
64 {
65     DWORD Read;
66 
67     while (TRUE)
68     {
69         /* Wait for a key press */
70         ReadConsoleInput(StdInput, Buffer, 1, &Read);
71 
72         if ((Buffer->EventType == KEY_EVENT) &&
73             (Buffer->Event.KeyEvent.bKeyDown != FALSE))
74         {
75             break;
76         }
77     }
78 }
79 
80 BOOLEAN
81 CONSOLE_ConInKeyPeek(
82     OUT PINPUT_RECORD Buffer)
83 {
84     DWORD Read = 0;
85 
86     while (TRUE)
87     {
88         /* Try to get a key press without blocking */
89         if (!PeekConsoleInput(StdInput, Buffer, 1, &Read))
90             return FALSE;
91         if (Read == 0)
92             return FALSE;
93 
94         /* Consume it */
95         ReadConsoleInput(StdInput, Buffer, 1, &Read);
96 
97         if ((Buffer->EventType == KEY_EVENT) &&
98             (Buffer->Event.KeyEvent.bKeyDown != FALSE))
99         {
100             return TRUE;
101         }
102     }
103 }
104 
105 VOID
106 CONSOLE_ConOutChar(
107     IN CHAR c)
108 {
109     DWORD Written;
110 
111     WriteConsole(
112         StdOutput,
113         &c,
114         1,
115         &Written,
116         NULL);
117 }
118 
119 VOID
120 CONSOLE_ConOutPuts(
121     IN LPCSTR szText)
122 {
123     DWORD Written;
124 
125     WriteConsole(
126         StdOutput,
127         szText,
128         (ULONG)strlen(szText),
129         &Written,
130         NULL);
131     WriteConsole(
132         StdOutput,
133         "\n",
134         1,
135         &Written,
136         NULL);
137 }
138 
139 VOID
140 CONSOLE_ConOutPrintfV(
141     IN LPCSTR szFormat,
142     IN va_list args)
143 {
144     CHAR szOut[256];
145     DWORD dwWritten;
146 
147     vsprintf(szOut, szFormat, args);
148 
149     WriteConsole(
150         StdOutput,
151         szOut,
152         (ULONG)strlen(szOut),
153         &dwWritten,
154         NULL);
155 }
156 
157 VOID
158 __cdecl
159 CONSOLE_ConOutPrintf(
160     IN LPCSTR szFormat,
161     ...)
162 {
163     va_list arg_ptr;
164 
165     va_start(arg_ptr, szFormat);
166     CONSOLE_ConOutPrintfV(szFormat, arg_ptr);
167     va_end(arg_ptr);
168 }
169 
170 BOOL
171 CONSOLE_Flush(VOID)
172 {
173     return FlushConsoleInputBuffer(StdInput);
174 }
175 
176 VOID
177 CONSOLE_GetCursorXY(
178     PSHORT x,
179     PSHORT y)
180 {
181     CONSOLE_SCREEN_BUFFER_INFO csbi;
182 
183     GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
184 
185     *x = csbi.dwCursorPosition.X;
186     *y = csbi.dwCursorPosition.Y;
187 }
188 
189 SHORT
190 CONSOLE_GetCursorX(VOID)
191 {
192     CONSOLE_SCREEN_BUFFER_INFO csbi;
193 
194     GetConsoleScreenBufferInfo(StdOutput, &csbi);
195 
196     return csbi.dwCursorPosition.X;
197 }
198 
199 SHORT
200 CONSOLE_GetCursorY(VOID)
201 {
202     CONSOLE_SCREEN_BUFFER_INFO csbi;
203 
204     GetConsoleScreenBufferInfo(StdOutput, &csbi);
205 
206     return csbi.dwCursorPosition.Y;
207 }
208 
209 VOID
210 CONSOLE_SetCursorType(
211     IN BOOL bInsert,
212     IN BOOL bVisible)
213 {
214     CONSOLE_CURSOR_INFO cci;
215 
216     cci.dwSize = bInsert ? 10 : 99;
217     cci.bVisible = bVisible;
218 
219     SetConsoleCursorInfo(StdOutput, &cci);
220 }
221 
222 VOID
223 CONSOLE_SetCursorXY(
224     IN SHORT x,
225     IN SHORT y)
226 {
227     COORD coPos;
228 
229     coPos.X = x;
230     coPos.Y = y;
231     SetConsoleCursorPosition(StdOutput, coPos);
232 }
233 
234 VOID
235 CONSOLE_ClearScreen(VOID)
236 {
237     COORD coPos;
238     DWORD Written;
239 
240     coPos.X = 0;
241     coPos.Y = 0;
242 
243     FillConsoleOutputAttribute(
244         StdOutput,
245         FOREGROUND_WHITE | BACKGROUND_BLUE,
246         xScreen * yScreen,
247         coPos,
248         &Written);
249 
250     FillConsoleOutputCharacterA(
251         StdOutput,
252         ' ',
253         xScreen * yScreen,
254         coPos,
255         &Written);
256 }
257 
258 VOID
259 CONSOLE_InvertTextXY(
260     IN SHORT x,
261     IN SHORT y,
262     IN SHORT col,
263     IN SHORT row)
264 {
265     COORD coPos;
266     DWORD Written;
267 
268     for (coPos.Y = y; coPos.Y < y + row; coPos.Y++)
269     {
270         coPos.X = x;
271 
272         FillConsoleOutputAttribute(
273             StdOutput,
274             FOREGROUND_BLUE | BACKGROUND_WHITE,
275             col,
276             coPos,
277             &Written);
278     }
279 }
280 
281 VOID
282 CONSOLE_NormalTextXY(
283     IN SHORT x,
284     IN SHORT y,
285     IN SHORT col,
286     IN SHORT row)
287 {
288     COORD coPos;
289     DWORD Written;
290 
291     for (coPos.Y = y; coPos.Y < y + row; coPos.Y++)
292     {
293         coPos.X = x;
294 
295         FillConsoleOutputAttribute(
296             StdOutput,
297             FOREGROUND_WHITE | BACKGROUND_BLUE,
298             col,
299             coPos,
300             &Written);
301     }
302 }
303 
304 VOID
305 CONSOLE_SetTextXY(
306     IN SHORT x,
307     IN SHORT y,
308     IN LPCSTR Text)
309 {
310     COORD coPos;
311     DWORD Written;
312 
313     coPos.X = x;
314     coPos.Y = y;
315 
316     WriteConsoleOutputCharacterA(
317         StdOutput,
318         Text,
319         (ULONG)strlen(Text),
320         coPos,
321         &Written);
322 }
323 
324 VOID
325 CONSOLE_ClearTextXY(IN SHORT x,
326                     IN SHORT y,
327                     IN SHORT Length)
328 {
329     COORD coPos;
330     DWORD Written;
331 
332     coPos.X = x;
333     coPos.Y = y;
334 
335     FillConsoleOutputCharacterA(StdOutput,
336                                 ' ',
337                                 Length,
338                                 coPos,
339                                 &Written);
340 }
341 
342 VOID
343 CONSOLE_SetInputTextXY(
344     IN SHORT x,
345     IN SHORT y,
346     IN SHORT len,
347     IN LPCWSTR Text)
348 {
349     COORD coPos;
350     SHORT Length;
351     DWORD Written;
352 
353     coPos.X = x;
354     coPos.Y = y;
355 
356     Length = (SHORT)wcslen(Text);
357     if (Length > len - 1)
358         Length = len - 1;
359 
360     FillConsoleOutputAttribute(
361         StdOutput,
362         BACKGROUND_WHITE,
363         len,
364         coPos,
365         &Written);
366 
367     WriteConsoleOutputCharacterW(
368         StdOutput,
369         Text,
370         (ULONG)Length,
371         coPos,
372         &Written);
373 
374     coPos.X += Length;
375     if (len > Length)
376     {
377         FillConsoleOutputCharacterA(
378             StdOutput,
379             ' ',
380             len - Length,
381             coPos,
382             &Written);
383     }
384 }
385 
386 VOID
387 CONSOLE_SetUnderlinedTextXY(
388     IN SHORT x,
389     IN SHORT y,
390     IN LPCSTR Text)
391 {
392     COORD coPos;
393     DWORD Length;
394     DWORD Written;
395 
396     coPos.X = x;
397     coPos.Y = y;
398 
399     Length = (ULONG)strlen(Text);
400 
401     WriteConsoleOutputCharacterA(
402         StdOutput,
403         Text,
404         Length,
405         coPos,
406         &Written);
407 
408     coPos.Y++;
409     FillConsoleOutputCharacterA(
410         StdOutput,
411         0xCD,
412         Length,
413         coPos,
414         &Written);
415 }
416 
417 VOID
418 CONSOLE_SetStatusTextXV(
419     IN SHORT x,
420     IN LPCSTR fmt,
421     IN va_list args)
422 {
423     COORD coPos;
424     DWORD Written;
425     CHAR Buffer[128];
426 
427     vsprintf(Buffer, fmt, args);
428 
429     coPos.X = 0;
430     coPos.Y = yScreen - 1;
431 
432     FillConsoleOutputAttribute(
433         StdOutput,
434         BACKGROUND_WHITE,
435         xScreen,
436         coPos,
437         &Written);
438 
439     FillConsoleOutputCharacterA(
440         StdOutput,
441         ' ',
442         xScreen,
443         coPos,
444         &Written);
445 
446     coPos.X = x;
447 
448     WriteConsoleOutputCharacterA(
449         StdOutput,
450         Buffer,
451         (ULONG)strlen(Buffer),
452         coPos,
453         &Written);
454 }
455 
456 VOID
457 __cdecl
458 CONSOLE_SetStatusTextX(
459     IN SHORT x,
460     IN LPCSTR fmt,
461     ...)
462 {
463     va_list ap;
464 
465     va_start(ap, fmt);
466     CONSOLE_SetStatusTextXV(x, fmt, ap);
467     va_end(ap);
468 }
469 
470 VOID
471 CONSOLE_SetStatusTextV(
472     IN LPCSTR fmt,
473     IN va_list args)
474 {
475     CONSOLE_SetStatusTextXV(0, fmt, args);
476 }
477 
478 VOID
479 __cdecl
480 CONSOLE_SetStatusText(
481     IN LPCSTR fmt,
482     ...)
483 {
484     va_list ap;
485 
486     va_start(ap, fmt);
487     CONSOLE_SetStatusTextV(fmt, ap);
488     va_end(ap);
489 }
490 
491 static
492 VOID
493 CONSOLE_ClearStatusTextX(IN SHORT x,
494                          IN SHORT Length)
495 {
496     COORD coPos;
497     DWORD Written;
498 
499     coPos.X = x;
500     coPos.Y = yScreen - 1;
501 
502     FillConsoleOutputCharacterA(StdOutput,
503                                 ' ',
504                                 Length,
505                                 coPos,
506                                 &Written);
507 }
508 
509 
510 VOID
511 __cdecl
512 CONSOLE_SetStatusTextAutoFitX(
513     IN SHORT x,
514     IN LPCSTR fmt, ...)
515 {
516     CHAR Buffer[128];
517     DWORD Length;
518     va_list ap;
519 
520     va_start(ap, fmt);
521     vsprintf(Buffer, fmt, ap);
522     va_end(ap);
523 
524     Length = (ULONG)strlen(Buffer);
525 
526     if (Length + x <= 79)
527     {
528         CONSOLE_SetStatusTextX (x , Buffer);
529     }
530     else
531     {
532         CONSOLE_SetStatusTextX (79 - Length , Buffer);
533     }
534 }
535 
536 VOID
537 CONSOLE_SetInvertedTextXY(
538     IN SHORT x,
539     IN SHORT y,
540     IN LPCSTR Text)
541 {
542     COORD coPos;
543     DWORD Length;
544     DWORD Written;
545 
546     coPos.X = x;
547     coPos.Y = y;
548 
549     Length = (ULONG)strlen(Text);
550 
551     FillConsoleOutputAttribute(
552         StdOutput,
553         FOREGROUND_BLUE | BACKGROUND_WHITE,
554         Length,
555         coPos,
556         &Written);
557 
558     WriteConsoleOutputCharacterA(
559         StdOutput,
560         Text,
561         Length,
562         coPos,
563         &Written);
564 }
565 
566 VOID
567 CONSOLE_SetHighlightedTextXY(
568     IN SHORT x,
569     IN SHORT y,
570     IN LPCSTR Text)
571 {
572     COORD coPos;
573     DWORD Length;
574     DWORD Written;
575 
576     coPos.X = x;
577     coPos.Y = y;
578 
579     Length = (ULONG)strlen(Text);
580 
581     FillConsoleOutputAttribute(
582         StdOutput,
583         FOREGROUND_WHITE | FOREGROUND_INTENSITY | BACKGROUND_BLUE,
584         Length,
585         coPos,
586         &Written);
587 
588     WriteConsoleOutputCharacterA(
589         StdOutput,
590         Text,
591         Length,
592         coPos,
593         &Written);
594 }
595 
596 VOID
597 __cdecl
598 CONSOLE_PrintTextXY(
599     IN SHORT x,
600     IN SHORT y,
601     IN LPCSTR fmt, ...)
602 {
603     CHAR buffer[512];
604     va_list ap;
605     COORD coPos;
606     DWORD Written;
607 
608     va_start(ap, fmt);
609     vsprintf(buffer, fmt, ap);
610     va_end(ap);
611 
612     coPos.X = x;
613     coPos.Y = y;
614 
615     WriteConsoleOutputCharacterA(
616         StdOutput,
617         buffer,
618         (ULONG)strlen(buffer),
619         coPos,
620         &Written);
621 }
622 
623 VOID
624 __cdecl
625 CONSOLE_PrintTextXYN(
626     IN SHORT x,
627     IN SHORT y,
628     IN SHORT len,
629     IN LPCSTR fmt, ...)
630 {
631     CHAR buffer[512];
632     va_list ap;
633     COORD coPos;
634     SHORT Length;
635     DWORD Written;
636 
637     va_start(ap, fmt);
638     vsprintf(buffer, fmt, ap);
639     va_end(ap);
640 
641     coPos.X = x;
642     coPos.Y = y;
643 
644     Length = (SHORT)strlen(buffer);
645     if (Length > len - 1)
646         Length = len - 1;
647 
648     WriteConsoleOutputCharacterA(
649         StdOutput,
650         buffer,
651         Length,
652         coPos,
653         &Written);
654 
655     coPos.X += Length;
656 
657     if (len > Length)
658     {
659         FillConsoleOutputCharacterA(
660             StdOutput,
661             ' ',
662             len - Length,
663             coPos,
664             &Written);
665     }
666 }
667 
668 VOID
669 CONSOLE_SetStyledText(
670     IN SHORT x,
671     IN SHORT y,
672     IN INT Flags,
673     IN LPCSTR Text)
674 {
675     COORD coPos;
676     DWORD Length;
677 
678     coPos.X = x;
679     coPos.Y = y;
680 
681     Length = (ULONG)strlen(Text);
682 
683     if (Flags & TEXT_TYPE_STATUS)
684     {
685         coPos.X = x;
686         coPos.Y = yScreen - 1;
687     }
688     else /* TEXT_TYPE_REGULAR (Default) */
689     {
690         coPos.X = x;
691         coPos.Y = y;
692     }
693 
694     if (Flags & TEXT_ALIGN_CENTER)
695     {
696         coPos.X = (xScreen - Length) /2;
697     }
698     else if(Flags & TEXT_ALIGN_RIGHT)
699     {
700         coPos.X = coPos.X - Length;
701 
702         if (Flags & TEXT_PADDING_SMALL)
703         {
704             coPos.X -= 1;
705         }
706         else if (Flags & TEXT_PADDING_MEDIUM)
707         {
708             coPos.X -= 2;
709         }
710         else if (Flags & TEXT_PADDING_BIG)
711         {
712             coPos.X -= 3;
713         }
714     }
715     else /* TEXT_ALIGN_LEFT (Default) */
716     {
717         if (Flags & TEXT_PADDING_SMALL)
718         {
719             coPos.X += 1;
720         }
721         else if (Flags & TEXT_PADDING_MEDIUM)
722         {
723             coPos.X += 2;
724         }
725         else if (Flags & TEXT_PADDING_BIG)
726         {
727             coPos.X += 3;
728         }
729     }
730 
731     if (Flags & TEXT_TYPE_STATUS)
732     {
733         CONSOLE_SetStatusTextX(coPos.X, Text);
734     }
735     else /* TEXT_TYPE_REGULAR (Default) */
736     {
737         if (Flags & TEXT_STYLE_HIGHLIGHT)
738         {
739             CONSOLE_SetHighlightedTextXY(coPos.X, coPos.Y, Text);
740         }
741         else if (Flags & TEXT_STYLE_UNDERLINE)
742         {
743             CONSOLE_SetUnderlinedTextXY(coPos.X, coPos.Y, Text);
744         }
745         else /* TEXT_STYLE_NORMAL (Default) */
746         {
747             CONSOLE_SetTextXY(coPos.X, coPos.Y, Text);
748         }
749     }
750 }
751 
752 
753 VOID
754 CONSOLE_ClearStyledText(IN SHORT x,
755                         IN SHORT y,
756                         IN INT Flags,
757                         IN SHORT Length)
758 {
759     COORD coPos;
760 
761     coPos.X = x;
762     coPos.Y = y;
763 
764     if (Flags & TEXT_TYPE_STATUS)
765     {
766         coPos.X = x;
767         coPos.Y = yScreen - 1;
768     }
769     else /* TEXT_TYPE_REGULAR (Default) */
770     {
771         coPos.X = x;
772         coPos.Y = y;
773     }
774 
775     if (Flags & TEXT_ALIGN_CENTER)
776     {
777         coPos.X = (xScreen - Length) /2;
778     }
779     else if(Flags & TEXT_ALIGN_RIGHT)
780     {
781         coPos.X = coPos.X - Length;
782 
783         if (Flags & TEXT_PADDING_SMALL)
784         {
785             coPos.X -= 1;
786         }
787         else if (Flags & TEXT_PADDING_MEDIUM)
788         {
789             coPos.X -= 2;
790         }
791         else if (Flags & TEXT_PADDING_BIG)
792         {
793             coPos.X -= 3;
794         }
795     }
796     else /* TEXT_ALIGN_LEFT (Default) */
797     {
798         if (Flags & TEXT_PADDING_SMALL)
799         {
800             coPos.X += 1;
801         }
802         else if (Flags & TEXT_PADDING_MEDIUM)
803         {
804             coPos.X += 2;
805         }
806         else if (Flags & TEXT_PADDING_BIG)
807         {
808             coPos.X += 3;
809         }
810     }
811 
812     if (Flags & TEXT_TYPE_STATUS)
813     {
814         CONSOLE_ClearStatusTextX(coPos.X, Length);
815     }
816     else /* TEXT_TYPE_REGULAR (Default) */
817     {
818         CONSOLE_ClearTextXY(coPos.X, coPos.Y, Length);
819     }
820 }
821 
822 /* EOF */
823