[USETUP] Introduce some -V functions for CONSOLE_ConOutPrintf, CONSOLE_SetStatusText...
[reactos.git] / base / setup / usetup / consup.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 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 static
325 VOID
326 CONSOLE_ClearTextXY(IN SHORT x,
327 IN SHORT y,
328 IN SHORT Length)
329 {
330 COORD coPos;
331 DWORD Written;
332
333 coPos.X = x;
334 coPos.Y = y;
335
336 FillConsoleOutputCharacterA(StdOutput,
337 ' ',
338 Length,
339 coPos,
340 &Written);
341 }
342
343 VOID
344 CONSOLE_SetInputTextXY(
345 IN SHORT x,
346 IN SHORT y,
347 IN SHORT len,
348 IN LPCWSTR Text)
349 {
350 COORD coPos;
351 SHORT Length;
352 DWORD Written;
353
354 coPos.X = x;
355 coPos.Y = y;
356
357 Length = (SHORT)wcslen(Text);
358 if (Length > len - 1)
359 Length = len - 1;
360
361 FillConsoleOutputAttribute(
362 StdOutput,
363 BACKGROUND_WHITE,
364 len,
365 coPos,
366 &Written);
367
368 WriteConsoleOutputCharacterW(
369 StdOutput,
370 Text,
371 (ULONG)Length,
372 coPos,
373 &Written);
374
375 coPos.X += Length;
376 if (len > Length)
377 {
378 FillConsoleOutputCharacterA(
379 StdOutput,
380 ' ',
381 len - Length,
382 coPos,
383 &Written);
384 }
385 }
386
387 VOID
388 CONSOLE_SetUnderlinedTextXY(
389 IN SHORT x,
390 IN SHORT y,
391 IN LPCSTR Text)
392 {
393 COORD coPos;
394 DWORD Length;
395 DWORD Written;
396
397 coPos.X = x;
398 coPos.Y = y;
399
400 Length = (ULONG)strlen(Text);
401
402 WriteConsoleOutputCharacterA(
403 StdOutput,
404 Text,
405 Length,
406 coPos,
407 &Written);
408
409 coPos.Y++;
410 FillConsoleOutputCharacterA(
411 StdOutput,
412 0xCD,
413 Length,
414 coPos,
415 &Written);
416 }
417
418 VOID
419 CONSOLE_SetStatusTextXV(
420 IN SHORT x,
421 IN LPCSTR fmt,
422 IN va_list args)
423 {
424 COORD coPos;
425 DWORD Written;
426 CHAR Buffer[128];
427
428 vsprintf(Buffer, fmt, args);
429
430 coPos.X = 0;
431 coPos.Y = yScreen - 1;
432
433 FillConsoleOutputAttribute(
434 StdOutput,
435 BACKGROUND_WHITE,
436 xScreen,
437 coPos,
438 &Written);
439
440 FillConsoleOutputCharacterA(
441 StdOutput,
442 ' ',
443 xScreen,
444 coPos,
445 &Written);
446
447 coPos.X = x;
448
449 WriteConsoleOutputCharacterA(
450 StdOutput,
451 Buffer,
452 (ULONG)strlen(Buffer),
453 coPos,
454 &Written);
455 }
456
457 VOID
458 __cdecl
459 CONSOLE_SetStatusTextX(
460 IN SHORT x,
461 IN LPCSTR fmt,
462 ...)
463 {
464 va_list ap;
465
466 va_start(ap, fmt);
467 CONSOLE_SetStatusTextXV(x, fmt, ap);
468 va_end(ap);
469 }
470
471 VOID
472 CONSOLE_SetStatusTextV(
473 IN LPCSTR fmt,
474 IN va_list args)
475 {
476 CONSOLE_SetStatusTextXV(0, fmt, args);
477 }
478
479 VOID
480 __cdecl
481 CONSOLE_SetStatusText(
482 IN LPCSTR fmt,
483 ...)
484 {
485 va_list ap;
486
487 va_start(ap, fmt);
488 CONSOLE_SetStatusTextV(fmt, ap);
489 va_end(ap);
490 }
491
492 static
493 VOID
494 CONSOLE_ClearStatusTextX(IN SHORT x,
495 IN SHORT Length)
496 {
497 COORD coPos;
498 DWORD Written;
499
500 coPos.X = x;
501 coPos.Y = yScreen - 1;
502
503 FillConsoleOutputCharacterA(StdOutput,
504 ' ',
505 Length,
506 coPos,
507 &Written);
508 }
509
510
511 VOID
512 __cdecl
513 CONSOLE_SetStatusTextAutoFitX(
514 IN SHORT x,
515 IN LPCSTR fmt, ...)
516 {
517 CHAR Buffer[128];
518 DWORD Length;
519 va_list ap;
520
521 va_start(ap, fmt);
522 vsprintf(Buffer, fmt, ap);
523 va_end(ap);
524
525 Length = (ULONG)strlen(Buffer);
526
527 if (Length + x <= 79)
528 {
529 CONSOLE_SetStatusTextX (x , Buffer);
530 }
531 else
532 {
533 CONSOLE_SetStatusTextX (79 - Length , Buffer);
534 }
535 }
536
537 VOID
538 CONSOLE_SetInvertedTextXY(
539 IN SHORT x,
540 IN SHORT y,
541 IN LPCSTR Text)
542 {
543 COORD coPos;
544 DWORD Length;
545 DWORD Written;
546
547 coPos.X = x;
548 coPos.Y = y;
549
550 Length = (ULONG)strlen(Text);
551
552 FillConsoleOutputAttribute(
553 StdOutput,
554 FOREGROUND_BLUE | BACKGROUND_WHITE,
555 Length,
556 coPos,
557 &Written);
558
559 WriteConsoleOutputCharacterA(
560 StdOutput,
561 Text,
562 Length,
563 coPos,
564 &Written);
565 }
566
567 VOID
568 CONSOLE_SetHighlightedTextXY(
569 IN SHORT x,
570 IN SHORT y,
571 IN LPCSTR Text)
572 {
573 COORD coPos;
574 DWORD Length;
575 DWORD Written;
576
577 coPos.X = x;
578 coPos.Y = y;
579
580 Length = (ULONG)strlen(Text);
581
582 FillConsoleOutputAttribute(
583 StdOutput,
584 FOREGROUND_WHITE | FOREGROUND_INTENSITY | BACKGROUND_BLUE,
585 Length,
586 coPos,
587 &Written);
588
589 WriteConsoleOutputCharacterA(
590 StdOutput,
591 Text,
592 Length,
593 coPos,
594 &Written);
595 }
596
597 VOID
598 __cdecl
599 CONSOLE_PrintTextXY(
600 IN SHORT x,
601 IN SHORT y,
602 IN LPCSTR fmt, ...)
603 {
604 CHAR buffer[512];
605 va_list ap;
606 COORD coPos;
607 DWORD Written;
608
609 va_start(ap, fmt);
610 vsprintf(buffer, fmt, ap);
611 va_end(ap);
612
613 coPos.X = x;
614 coPos.Y = y;
615
616 WriteConsoleOutputCharacterA(
617 StdOutput,
618 buffer,
619 (ULONG)strlen(buffer),
620 coPos,
621 &Written);
622 }
623
624 VOID
625 __cdecl
626 CONSOLE_PrintTextXYN(
627 IN SHORT x,
628 IN SHORT y,
629 IN SHORT len,
630 IN LPCSTR fmt, ...)
631 {
632 CHAR buffer[512];
633 va_list ap;
634 COORD coPos;
635 SHORT Length;
636 DWORD Written;
637
638 va_start(ap, fmt);
639 vsprintf(buffer, fmt, ap);
640 va_end(ap);
641
642 coPos.X = x;
643 coPos.Y = y;
644
645 Length = (SHORT)strlen(buffer);
646 if (Length > len - 1)
647 Length = len - 1;
648
649 WriteConsoleOutputCharacterA(
650 StdOutput,
651 buffer,
652 Length,
653 coPos,
654 &Written);
655
656 coPos.X += Length;
657
658 if (len > Length)
659 {
660 FillConsoleOutputCharacterA(
661 StdOutput,
662 ' ',
663 len - Length,
664 coPos,
665 &Written);
666 }
667 }
668
669 VOID
670 CONSOLE_SetStyledText(
671 IN SHORT x,
672 IN SHORT y,
673 IN INT Flags,
674 IN LPCSTR Text)
675 {
676 COORD coPos;
677 DWORD Length;
678
679 coPos.X = x;
680 coPos.Y = y;
681
682 Length = (ULONG)strlen(Text);
683
684 if (Flags & TEXT_TYPE_STATUS)
685 {
686 coPos.X = x;
687 coPos.Y = yScreen - 1;
688 }
689 else /* TEXT_TYPE_REGULAR (Default) */
690 {
691 coPos.X = x;
692 coPos.Y = y;
693 }
694
695 if (Flags & TEXT_ALIGN_CENTER)
696 {
697 coPos.X = (xScreen - Length) /2;
698 }
699 else if(Flags & TEXT_ALIGN_RIGHT)
700 {
701 coPos.X = coPos.X - Length;
702
703 if (Flags & TEXT_PADDING_SMALL)
704 {
705 coPos.X -= 1;
706 }
707 else if (Flags & TEXT_PADDING_MEDIUM)
708 {
709 coPos.X -= 2;
710 }
711 else if (Flags & TEXT_PADDING_BIG)
712 {
713 coPos.X -= 3;
714 }
715 }
716 else /* TEXT_ALIGN_LEFT (Default) */
717 {
718 if (Flags & TEXT_PADDING_SMALL)
719 {
720 coPos.X += 1;
721 }
722 else if (Flags & TEXT_PADDING_MEDIUM)
723 {
724 coPos.X += 2;
725 }
726 else if (Flags & TEXT_PADDING_BIG)
727 {
728 coPos.X += 3;
729 }
730 }
731
732 if (Flags & TEXT_TYPE_STATUS)
733 {
734 CONSOLE_SetStatusTextX(coPos.X, Text);
735 }
736 else /* TEXT_TYPE_REGULAR (Default) */
737 {
738 if (Flags & TEXT_STYLE_HIGHLIGHT)
739 {
740 CONSOLE_SetHighlightedTextXY(coPos.X, coPos.Y, Text);
741 }
742 else if (Flags & TEXT_STYLE_UNDERLINE)
743 {
744 CONSOLE_SetUnderlinedTextXY(coPos.X, coPos.Y, Text);
745 }
746 else /* TEXT_STYLE_NORMAL (Default) */
747 {
748 CONSOLE_SetTextXY(coPos.X, coPos.Y, Text);
749 }
750 }
751 }
752
753
754 VOID
755 CONSOLE_ClearStyledText(IN SHORT x,
756 IN SHORT y,
757 IN INT Flags,
758 IN SHORT Length)
759 {
760 COORD coPos;
761
762 coPos.X = x;
763 coPos.Y = y;
764
765 if (Flags & TEXT_TYPE_STATUS)
766 {
767 coPos.X = x;
768 coPos.Y = yScreen - 1;
769 }
770 else /* TEXT_TYPE_REGULAR (Default) */
771 {
772 coPos.X = x;
773 coPos.Y = y;
774 }
775
776 if (Flags & TEXT_ALIGN_CENTER)
777 {
778 coPos.X = (xScreen - Length) /2;
779 }
780 else if(Flags & TEXT_ALIGN_RIGHT)
781 {
782 coPos.X = coPos.X - Length;
783
784 if (Flags & TEXT_PADDING_SMALL)
785 {
786 coPos.X -= 1;
787 }
788 else if (Flags & TEXT_PADDING_MEDIUM)
789 {
790 coPos.X -= 2;
791 }
792 else if (Flags & TEXT_PADDING_BIG)
793 {
794 coPos.X -= 3;
795 }
796 }
797 else /* TEXT_ALIGN_LEFT (Default) */
798 {
799 if (Flags & TEXT_PADDING_SMALL)
800 {
801 coPos.X += 1;
802 }
803 else if (Flags & TEXT_PADDING_MEDIUM)
804 {
805 coPos.X += 2;
806 }
807 else if (Flags & TEXT_PADDING_BIG)
808 {
809 coPos.X += 3;
810 }
811 }
812
813 if (Flags & TEXT_TYPE_STATUS)
814 {
815 CONSOLE_ClearStatusTextX(coPos.X, Length);
816 }
817 else /* TEXT_TYPE_REGULAR (Default) */
818 {
819 CONSOLE_ClearTextXY(coPos.X, coPos.Y, Length);
820 }
821 }
822
823 /* EOF */