3c4bf3d011738da11a5350ca24a0a68ff05aa343
[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_ConOutPrintf(
141 IN LPCSTR szFormat, ...)
142 {
143 CHAR szOut[256];
144 DWORD dwWritten;
145 va_list arg_ptr;
146
147 va_start(arg_ptr, szFormat);
148 vsprintf(szOut, szFormat, arg_ptr);
149 va_end(arg_ptr);
150
151 WriteConsole(
152 StdOutput,
153 szOut,
154 (ULONG)strlen(szOut),
155 &dwWritten,
156 NULL);
157 }
158
159 BOOL
160 CONSOLE_Flush(VOID)
161 {
162 return FlushConsoleInputBuffer(StdInput);
163 }
164
165 VOID
166 CONSOLE_GetCursorXY(
167 PSHORT x,
168 PSHORT y)
169 {
170 CONSOLE_SCREEN_BUFFER_INFO csbi;
171
172 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
173
174 *x = csbi.dwCursorPosition.X;
175 *y = csbi.dwCursorPosition.Y;
176 }
177
178 SHORT
179 CONSOLE_GetCursorX(VOID)
180 {
181 CONSOLE_SCREEN_BUFFER_INFO csbi;
182
183 GetConsoleScreenBufferInfo(StdOutput, &csbi);
184
185 return csbi.dwCursorPosition.X;
186 }
187
188 SHORT
189 CONSOLE_GetCursorY(VOID)
190 {
191 CONSOLE_SCREEN_BUFFER_INFO csbi;
192
193 GetConsoleScreenBufferInfo(StdOutput, &csbi);
194
195 return csbi.dwCursorPosition.Y;
196 }
197
198 VOID
199 CONSOLE_SetCursorType(
200 IN BOOL bInsert,
201 IN BOOL bVisible)
202 {
203 CONSOLE_CURSOR_INFO cci;
204
205 cci.dwSize = bInsert ? 10 : 99;
206 cci.bVisible = bVisible;
207
208 SetConsoleCursorInfo(StdOutput, &cci);
209 }
210
211 VOID
212 CONSOLE_SetCursorXY(
213 IN SHORT x,
214 IN SHORT y)
215 {
216 COORD coPos;
217
218 coPos.X = x;
219 coPos.Y = y;
220 SetConsoleCursorPosition(StdOutput, coPos);
221 }
222
223 VOID
224 CONSOLE_ClearScreen(VOID)
225 {
226 COORD coPos;
227 DWORD Written;
228
229 coPos.X = 0;
230 coPos.Y = 0;
231
232 FillConsoleOutputAttribute(
233 StdOutput,
234 FOREGROUND_WHITE | BACKGROUND_BLUE,
235 xScreen * yScreen,
236 coPos,
237 &Written);
238
239 FillConsoleOutputCharacterA(
240 StdOutput,
241 ' ',
242 xScreen * yScreen,
243 coPos,
244 &Written);
245 }
246
247 VOID
248 CONSOLE_InvertTextXY(
249 IN SHORT x,
250 IN SHORT y,
251 IN SHORT col,
252 IN SHORT row)
253 {
254 COORD coPos;
255 DWORD Written;
256
257 for (coPos.Y = y; coPos.Y < y + row; coPos.Y++)
258 {
259 coPos.X = x;
260
261 FillConsoleOutputAttribute(
262 StdOutput,
263 FOREGROUND_BLUE | BACKGROUND_WHITE,
264 col,
265 coPos,
266 &Written);
267 }
268 }
269
270 VOID
271 CONSOLE_NormalTextXY(
272 IN SHORT x,
273 IN SHORT y,
274 IN SHORT col,
275 IN SHORT row)
276 {
277 COORD coPos;
278 DWORD Written;
279
280 for (coPos.Y = y; coPos.Y < y + row; coPos.Y++)
281 {
282 coPos.X = x;
283
284 FillConsoleOutputAttribute(
285 StdOutput,
286 FOREGROUND_WHITE | BACKGROUND_BLUE,
287 col,
288 coPos,
289 &Written);
290 }
291 }
292
293 VOID
294 CONSOLE_SetTextXY(
295 IN SHORT x,
296 IN SHORT y,
297 IN LPCSTR Text)
298 {
299 COORD coPos;
300 DWORD Written;
301
302 coPos.X = x;
303 coPos.Y = y;
304
305 WriteConsoleOutputCharacterA(
306 StdOutput,
307 Text,
308 (ULONG)strlen(Text),
309 coPos,
310 &Written);
311 }
312
313 static
314 VOID
315 CONSOLE_ClearTextXY(IN SHORT x,
316 IN SHORT y,
317 IN SHORT Length)
318 {
319 COORD coPos;
320 DWORD Written;
321
322 coPos.X = x;
323 coPos.Y = y;
324
325 FillConsoleOutputCharacterA(StdOutput,
326 ' ',
327 Length,
328 coPos,
329 &Written);
330 }
331
332 VOID
333 CONSOLE_SetInputTextXY(
334 IN SHORT x,
335 IN SHORT y,
336 IN SHORT len,
337 IN LPCWSTR Text)
338 {
339 COORD coPos;
340 SHORT Length;
341 DWORD Written;
342
343 coPos.X = x;
344 coPos.Y = y;
345
346 Length = (SHORT)wcslen(Text);
347 if (Length > len - 1)
348 Length = len - 1;
349
350 FillConsoleOutputAttribute(
351 StdOutput,
352 BACKGROUND_WHITE,
353 len,
354 coPos,
355 &Written);
356
357 WriteConsoleOutputCharacterW(
358 StdOutput,
359 Text,
360 (ULONG)Length,
361 coPos,
362 &Written);
363
364 coPos.X += Length;
365 if (len > Length)
366 {
367 FillConsoleOutputCharacterA(
368 StdOutput,
369 ' ',
370 len - Length,
371 coPos,
372 &Written);
373 }
374 }
375
376 VOID
377 CONSOLE_SetUnderlinedTextXY(
378 IN SHORT x,
379 IN SHORT y,
380 IN LPCSTR Text)
381 {
382 COORD coPos;
383 DWORD Length;
384 DWORD Written;
385
386 coPos.X = x;
387 coPos.Y = y;
388
389 Length = (ULONG)strlen(Text);
390
391 WriteConsoleOutputCharacterA(
392 StdOutput,
393 Text,
394 Length,
395 coPos,
396 &Written);
397
398 coPos.Y++;
399 FillConsoleOutputCharacterA(
400 StdOutput,
401 0xCD,
402 Length,
403 coPos,
404 &Written);
405 }
406
407 VOID
408 CONSOLE_SetStatusText(
409 IN LPCSTR fmt, ...)
410 {
411 CHAR Buffer[128];
412 va_list ap;
413 COORD coPos;
414 DWORD Written;
415
416 va_start(ap, fmt);
417 vsprintf(Buffer, fmt, ap);
418 va_end(ap);
419
420 coPos.X = 0;
421 coPos.Y = yScreen - 1;
422
423 FillConsoleOutputAttribute(
424 StdOutput,
425 BACKGROUND_WHITE,
426 xScreen,
427 coPos,
428 &Written);
429
430 FillConsoleOutputCharacterA(
431 StdOutput,
432 ' ',
433 xScreen,
434 coPos,
435 &Written);
436
437 WriteConsoleOutputCharacterA(
438 StdOutput,
439 Buffer,
440 (ULONG)strlen(Buffer),
441 coPos,
442 &Written);
443 }
444
445 VOID
446 CONSOLE_SetStatusTextX(
447 IN SHORT x,
448 IN LPCSTR fmt, ...)
449 {
450 CHAR Buffer[128];
451 va_list ap;
452 COORD coPos;
453 DWORD Written;
454
455 va_start(ap, fmt);
456 vsprintf(Buffer, fmt, ap);
457 va_end(ap);
458
459 coPos.X = 0;
460 coPos.Y = yScreen - 1;
461
462 FillConsoleOutputAttribute(
463 StdOutput,
464 BACKGROUND_WHITE,
465 xScreen,
466 coPos,
467 &Written);
468
469 FillConsoleOutputCharacterA(
470 StdOutput,
471 ' ',
472 xScreen,
473 coPos,
474 &Written);
475
476 coPos.X = x;
477
478 WriteConsoleOutputCharacterA(
479 StdOutput,
480 Buffer,
481 (ULONG)strlen(Buffer),
482 coPos,
483 &Written);
484 }
485
486 static
487 VOID
488 CONSOLE_ClearStatusTextX(IN SHORT x,
489 IN SHORT Length)
490 {
491 COORD coPos;
492 DWORD Written;
493
494 coPos.X = x;
495 coPos.Y = yScreen - 1;
496
497 FillConsoleOutputCharacterA(StdOutput,
498 ' ',
499 Length,
500 coPos,
501 &Written);
502 }
503
504
505 VOID
506 CONSOLE_SetStatusTextAutoFitX(
507 IN SHORT x,
508 IN LPCSTR fmt, ...)
509 {
510 CHAR Buffer[128];
511 DWORD Length;
512 va_list ap;
513
514 va_start(ap, fmt);
515 vsprintf(Buffer, fmt, ap);
516 va_end(ap);
517
518 Length = (ULONG)strlen(Buffer);
519
520 if (Length + x <= 79)
521 {
522 CONSOLE_SetStatusTextX (x , Buffer);
523 }
524 else
525 {
526 CONSOLE_SetStatusTextX (79 - Length , Buffer);
527 }
528 }
529
530 VOID
531 CONSOLE_SetInvertedTextXY(
532 IN SHORT x,
533 IN SHORT y,
534 IN LPCSTR Text)
535 {
536 COORD coPos;
537 DWORD Length;
538 DWORD Written;
539
540 coPos.X = x;
541 coPos.Y = y;
542
543 Length = (ULONG)strlen(Text);
544
545 FillConsoleOutputAttribute(
546 StdOutput,
547 FOREGROUND_BLUE | BACKGROUND_WHITE,
548 Length,
549 coPos,
550 &Written);
551
552 WriteConsoleOutputCharacterA(
553 StdOutput,
554 Text,
555 Length,
556 coPos,
557 &Written);
558 }
559
560 VOID
561 CONSOLE_SetHighlightedTextXY(
562 IN SHORT x,
563 IN SHORT y,
564 IN LPCSTR Text)
565 {
566 COORD coPos;
567 DWORD Length;
568 DWORD Written;
569
570 coPos.X = x;
571 coPos.Y = y;
572
573 Length = (ULONG)strlen(Text);
574
575 FillConsoleOutputAttribute(
576 StdOutput,
577 FOREGROUND_WHITE | FOREGROUND_INTENSITY | BACKGROUND_BLUE,
578 Length,
579 coPos,
580 &Written);
581
582 WriteConsoleOutputCharacterA(
583 StdOutput,
584 Text,
585 Length,
586 coPos,
587 &Written);
588 }
589
590 VOID
591 CONSOLE_PrintTextXY(
592 IN SHORT x,
593 IN SHORT y,
594 IN LPCSTR fmt, ...)
595 {
596 CHAR buffer[512];
597 va_list ap;
598 COORD coPos;
599 DWORD Written;
600
601 va_start(ap, fmt);
602 vsprintf(buffer, fmt, ap);
603 va_end(ap);
604
605 coPos.X = x;
606 coPos.Y = y;
607
608 WriteConsoleOutputCharacterA(
609 StdOutput,
610 buffer,
611 (ULONG)strlen(buffer),
612 coPos,
613 &Written);
614 }
615
616 VOID
617 CONSOLE_PrintTextXYN(
618 IN SHORT x,
619 IN SHORT y,
620 IN SHORT len,
621 IN LPCSTR fmt, ...)
622 {
623 CHAR buffer[512];
624 va_list ap;
625 COORD coPos;
626 SHORT Length;
627 DWORD Written;
628
629 va_start(ap, fmt);
630 vsprintf(buffer, fmt, ap);
631 va_end(ap);
632
633 coPos.X = x;
634 coPos.Y = y;
635
636 Length = (SHORT)strlen(buffer);
637 if (Length > len - 1)
638 Length = len - 1;
639
640 WriteConsoleOutputCharacterA(
641 StdOutput,
642 buffer,
643 Length,
644 coPos,
645 &Written);
646
647 coPos.X += Length;
648
649 if (len > Length)
650 {
651 FillConsoleOutputCharacterA(
652 StdOutput,
653 ' ',
654 len - Length,
655 coPos,
656 &Written);
657 }
658 }
659
660 VOID
661 CONSOLE_SetStyledText(
662 IN SHORT x,
663 IN SHORT y,
664 IN INT Flags,
665 IN LPCSTR Text)
666 {
667 COORD coPos;
668 DWORD Length;
669
670 coPos.X = x;
671 coPos.Y = y;
672
673 Length = (ULONG)strlen(Text);
674
675 if (Flags & TEXT_TYPE_STATUS)
676 {
677 coPos.X = x;
678 coPos.Y = yScreen - 1;
679 }
680 else /* TEXT_TYPE_REGULAR (Default) */
681 {
682 coPos.X = x;
683 coPos.Y = y;
684 }
685
686 if (Flags & TEXT_ALIGN_CENTER)
687 {
688 coPos.X = (xScreen - Length) /2;
689 }
690 else if(Flags & TEXT_ALIGN_RIGHT)
691 {
692 coPos.X = coPos.X - Length;
693
694 if (Flags & TEXT_PADDING_SMALL)
695 {
696 coPos.X -= 1;
697 }
698 else if (Flags & TEXT_PADDING_MEDIUM)
699 {
700 coPos.X -= 2;
701 }
702 else if (Flags & TEXT_PADDING_BIG)
703 {
704 coPos.X -= 3;
705 }
706 }
707 else /* TEXT_ALIGN_LEFT (Default) */
708 {
709 if (Flags & TEXT_PADDING_SMALL)
710 {
711 coPos.X += 1;
712 }
713 else if (Flags & TEXT_PADDING_MEDIUM)
714 {
715 coPos.X += 2;
716 }
717 else if (Flags & TEXT_PADDING_BIG)
718 {
719 coPos.X += 3;
720 }
721 }
722
723 if (Flags & TEXT_TYPE_STATUS)
724 {
725 CONSOLE_SetStatusTextX(coPos.X, Text);
726 }
727 else /* TEXT_TYPE_REGULAR (Default) */
728 {
729 if (Flags & TEXT_STYLE_HIGHLIGHT)
730 {
731 CONSOLE_SetHighlightedTextXY(coPos.X, coPos.Y, Text);
732 }
733 else if (Flags & TEXT_STYLE_UNDERLINE)
734 {
735 CONSOLE_SetUnderlinedTextXY(coPos.X, coPos.Y, Text);
736 }
737 else /* TEXT_STYLE_NORMAL (Default) */
738 {
739 CONSOLE_SetTextXY(coPos.X, coPos.Y, Text);
740 }
741 }
742 }
743
744
745 VOID
746 CONSOLE_ClearStyledText(IN SHORT x,
747 IN SHORT y,
748 IN INT Flags,
749 IN SHORT Length)
750 {
751 COORD coPos;
752
753 coPos.X = x;
754 coPos.Y = y;
755
756 if (Flags & TEXT_TYPE_STATUS)
757 {
758 coPos.X = x;
759 coPos.Y = yScreen - 1;
760 }
761 else /* TEXT_TYPE_REGULAR (Default) */
762 {
763 coPos.X = x;
764 coPos.Y = y;
765 }
766
767 if (Flags & TEXT_ALIGN_CENTER)
768 {
769 coPos.X = (xScreen - Length) /2;
770 }
771 else if(Flags & TEXT_ALIGN_RIGHT)
772 {
773 coPos.X = coPos.X - Length;
774
775 if (Flags & TEXT_PADDING_SMALL)
776 {
777 coPos.X -= 1;
778 }
779 else if (Flags & TEXT_PADDING_MEDIUM)
780 {
781 coPos.X -= 2;
782 }
783 else if (Flags & TEXT_PADDING_BIG)
784 {
785 coPos.X -= 3;
786 }
787 }
788 else /* TEXT_ALIGN_LEFT (Default) */
789 {
790 if (Flags & TEXT_PADDING_SMALL)
791 {
792 coPos.X += 1;
793 }
794 else if (Flags & TEXT_PADDING_MEDIUM)
795 {
796 coPos.X += 2;
797 }
798 else if (Flags & TEXT_PADDING_BIG)
799 {
800 coPos.X += 3;
801 }
802 }
803
804 if (Flags & TEXT_TYPE_STATUS)
805 {
806 CONSOLE_ClearStatusTextX(coPos.X, Length);
807 }
808 else /* TEXT_TYPE_REGULAR (Default) */
809 {
810 CONSOLE_ClearTextXY(coPos.X, coPos.Y, Length);
811 }
812 }
813
814 /* EOF */