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