3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
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.
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.
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.
22 PVOID TextVideoBuffer
= NULL
;
23 extern BOOLEAN UiDrawTime
;
24 extern BOOLEAN UiMinimal
;
25 extern void ofw_print_string(const char *);
26 extern void ofw_print_number(int x
);
29 * printf() - prints formatted text to stdout
30 * originally from GRUB
32 int printf(const char *format
, ... )
36 char c
, *ptr
, str
[16];
38 while ((c
= *(format
++)))
46 switch (c
= *(format
++))
48 case 'd': case 'u': case 'x': {
49 unsigned long x
= va_arg(ap
, unsigned long);
59 MachConsPutChar(*(ptr
++));
63 case 'c': MachConsPutChar((va_arg(ap
,int))&0xff); break;
66 ptr
= va_arg(ap
,char *);
68 while ((c
= *(ptr
++)))
77 printf("\nprintf() invalid format specifier - %%%c\n", c
);
88 BOOLEAN
TuiInitialize(VOID
)
90 MachVideoClearScreen(ATTR(COLOR_WHITE
, COLOR_BLACK
));
91 MachVideoHideShowTextCursor(FALSE
);
93 TextVideoBuffer
= VideoAllocateOffScreenBuffer();
94 if (TextVideoBuffer
== NULL
)
102 VOID
TuiUnInitialize(VOID
)
104 if (UiUseSpecialEffects
)
110 MachVideoSetDisplayMode(NULL
, FALSE
);
113 //VideoClearScreen();
114 MachVideoHideShowTextCursor(TRUE
);
117 VOID
TuiDrawBackdrop(VOID
)
122 // Fill in a black background
132 // Update the screen buffer
134 VideoCopyOffScreenBufferToVRAM();
139 // Fill in the background (excluding title box & status bar)
142 TUI_TITLE_BOX_CHAR_HEIGHT
,
146 ATTR(UiBackdropFgColor
, UiBackdropBgColor
));
149 // Draw the title box
154 TUI_TITLE_BOX_CHAR_HEIGHT
- 1,
159 ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
166 GetFreeLoaderVersionString(),
167 ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
175 ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
179 ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
184 TuiDrawText(UiScreenWidth
- 16, 3, /*"F1 for Help"*/"F8 for Options", ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
189 TuiDrawText( (UiScreenWidth
/ 2) - (strlen(UiTitleBoxTitleText
) / 2),
192 ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
197 TuiDrawStatusText("Welcome to FreeLoader!");
200 // Update the date & time
204 VideoCopyOffScreenBufferToVRAM();
209 * This function assumes coordinates are zero-based
211 VOID
TuiFillArea(ULONG Left
, ULONG Top
, ULONG Right
, ULONG Bottom
, CHAR FillChar
, UCHAR Attr
/* Color Attributes */)
213 PUCHAR ScreenMemory
= (PUCHAR
)TextVideoBuffer
;
216 // Clip the area to the screen
217 if ((Left
>= UiScreenWidth
) || (Top
>= UiScreenHeight
))
221 if (Right
>= UiScreenWidth
)
223 Right
= UiScreenWidth
- 1;
225 if (Bottom
>= UiScreenHeight
)
227 Bottom
= UiScreenHeight
- 1;
230 // Loop through each line and fill it in
231 for (i
=Top
; i
<=Bottom
; i
++)
233 // Loop through each character (column) in the line and fill it in
234 for (j
=Left
; j
<=Right
; j
++)
236 ScreenMemory
[((i
*2)*UiScreenWidth
)+(j
*2)] = (UCHAR
)FillChar
;
237 ScreenMemory
[((i
*2)*UiScreenWidth
)+(j
*2)+1] = Attr
;
244 * This function assumes coordinates are zero-based
246 VOID
TuiDrawShadow(ULONG Left
, ULONG Top
, ULONG Right
, ULONG Bottom
)
248 PUCHAR ScreenMemory
= (PUCHAR
)TextVideoBuffer
;
251 // Shade the bottom of the area
252 if (Bottom
< (UiScreenHeight
- 1))
254 if (UiScreenHeight
< 34)
263 for (; Idx
<=Right
; Idx
++)
265 ScreenMemory
[(((Bottom
+1)*2)*UiScreenWidth
)+(Idx
*2)+1] = ATTR(COLOR_GRAY
, COLOR_BLACK
);
269 // Shade the right of the area
270 if (Right
< (UiScreenWidth
- 1))
272 for (Idx
=Top
+1; Idx
<=Bottom
; Idx
++)
274 ScreenMemory
[((Idx
*2)*UiScreenWidth
)+((Right
+1)*2)+1] = ATTR(COLOR_GRAY
, COLOR_BLACK
);
277 if (UiScreenHeight
< 34)
279 if ((Right
+ 1) < (UiScreenWidth
- 1))
281 for (Idx
=Top
+1; Idx
<=Bottom
; Idx
++)
283 ScreenMemory
[((Idx
*2)*UiScreenWidth
)+((Right
+2)*2)+1] = ATTR(COLOR_GRAY
, COLOR_BLACK
);
288 // Shade the bottom right corner
289 if ((Right
< (UiScreenWidth
- 1)) && (Bottom
< (UiScreenHeight
- 1)))
291 ScreenMemory
[(((Bottom
+1)*2)*UiScreenWidth
)+((Right
+1)*2)+1] = ATTR(COLOR_GRAY
, COLOR_BLACK
);
293 if (UiScreenHeight
< 34)
295 if (((Right
+ 1) < (UiScreenWidth
- 1)) && (Bottom
< (UiScreenHeight
- 1)))
297 ScreenMemory
[(((Bottom
+1)*2)*UiScreenWidth
)+((Right
+2)*2)+1] = ATTR(COLOR_GRAY
, COLOR_BLACK
);
304 * This function assumes coordinates are zero-based
306 VOID
TuiDrawBox(ULONG Left
, ULONG Top
, ULONG Right
, ULONG Bottom
, UCHAR VertStyle
, UCHAR HorzStyle
, BOOLEAN Fill
, BOOLEAN Shadow
, UCHAR Attr
)
308 UCHAR ULCorner
, URCorner
, LLCorner
, LRCorner
;
310 // Calculate the corner values
311 if (HorzStyle
== HORZ
)
313 if (VertStyle
== VERT
)
320 else // VertStyle == D_VERT
328 else // HorzStyle == D_HORZ
330 if (VertStyle
== VERT
)
337 else // VertStyle == D_VERT
346 // Fill in box background
349 TuiFillArea(Left
, Top
, Right
, Bottom
, ' ', Attr
);
353 TuiFillArea(Left
, Top
, Left
, Top
, ULCorner
, Attr
);
354 TuiFillArea(Right
, Top
, Right
, Top
, URCorner
, Attr
);
355 TuiFillArea(Left
, Bottom
, Left
, Bottom
, LLCorner
, Attr
);
356 TuiFillArea(Right
, Bottom
, Right
, Bottom
, LRCorner
, Attr
);
359 TuiFillArea(Left
, Top
+1, Left
, Bottom
-1, VertStyle
, Attr
);
361 TuiFillArea(Left
+1, Top
, Right
-1, Top
, HorzStyle
, Attr
);
362 // Fill in right line
363 TuiFillArea(Right
, Top
+1, Right
, Bottom
-1, VertStyle
, Attr
);
364 // Fill in bottom line
365 TuiFillArea(Left
+1, Bottom
, Right
-1, Bottom
, HorzStyle
, Attr
);
370 TuiDrawShadow(Left
, Top
, Right
, Bottom
);
376 * This function assumes coordinates are zero-based
378 VOID
TuiDrawText(ULONG X
, ULONG Y
, PCSTR Text
, UCHAR Attr
)
380 PUCHAR ScreenMemory
= (PUCHAR
)TextVideoBuffer
;
384 for (i
=X
, j
=0; Text
[j
] && i
<UiScreenWidth
; i
++,j
++)
386 ScreenMemory
[((Y
*2)*UiScreenWidth
)+(i
*2)] = (UCHAR
)Text
[j
];
387 ScreenMemory
[((Y
*2)*UiScreenWidth
)+(i
*2)+1] = Attr
;
391 VOID
TuiDrawCenteredText(ULONG Left
, ULONG Top
, ULONG Right
, ULONG Bottom
, PCSTR TextString
, UCHAR Attr
)
396 ULONG LineBreakCount
;
405 TextLength
= strlen(TextString
);
407 // Count the new lines and the box width
411 for (Index
=0; Index
<TextLength
; Index
++)
413 if (TextString
[Index
] == '\n')
420 if ((Index
- LastIndex
) > BoxWidth
)
422 BoxWidth
= (Index
- LastIndex
);
427 BoxHeight
= LineBreakCount
+ 1;
429 RealLeft
= (((Right
- Left
) - BoxWidth
) / 2) + Left
;
430 RealTop
= (((Bottom
- Top
) - BoxHeight
) / 2) + Top
;
433 for (Index
=0; Index
<TextLength
; Index
++)
435 if (TextString
[Index
] == '\n')
442 X
= RealLeft
+ LastIndex
;
445 Temp
[0] = TextString
[Index
];
447 TuiDrawText(X
, Y
, Temp
, Attr
);
452 VOID
TuiDrawStatusText(PCSTR StatusText
)
457 // Minimal UI doesn't have a status bar
459 if (UiMinimal
) return;
461 TuiDrawText(0, UiScreenHeight
-1, " ", ATTR(UiStatusBarFgColor
, UiStatusBarBgColor
));
462 TuiDrawText(1, UiScreenHeight
-1, StatusText
, ATTR(UiStatusBarFgColor
, UiStatusBarBgColor
));
464 for (i
=strlen(StatusText
)+1; i
<UiScreenWidth
; i
++)
466 TuiDrawText(i
, UiScreenHeight
-1, " ", ATTR(UiStatusBarFgColor
, UiStatusBarBgColor
));
469 VideoCopyOffScreenBufferToVRAM();
472 VOID
TuiUpdateDateTime(VOID
)
474 ULONG Year
, Month
, Day
;
475 ULONG Hour
, Minute
, Second
;
479 BOOLEAN PMHour
= FALSE
;
481 /* Don't draw the time if this has been disabled */
482 if (!UiDrawTime
) return;
484 MachRTCGetCurrentDateTime(&Year
, &Month
, &Day
, &Hour
, &Minute
, &Second
);
485 if (Year
< 1 || 9999 < Year
|| Month
< 1 || 12 < Month
|| Day
< 1 ||
486 31 < Day
|| 23 < Hour
|| 59 < Minute
|| 59 < Second
)
488 /* This happens on QEmu sometimes. We just skip updating */
491 // Get the month name
492 strcpy(DateString
, UiMonthNames
[Month
- 1]);
494 _itoa(Day
, TempString
, 10);
495 // Get the day postfix
496 if (1 == Day
|| 21 == Day
|| 31 == Day
)
498 strcat(TempString
, "st");
500 else if (2 == Day
|| 22 == Day
)
502 strcat(TempString
, "nd");
504 else if (3 == Day
|| 23 == Day
)
506 strcat(TempString
, "rd");
510 strcat(TempString
, "th");
513 // Add the day to the date
514 strcat(DateString
, TempString
);
515 strcat(DateString
, " ");
517 // Get the year and add it to the date
518 _itoa(Year
, TempString
, 10);
519 strcat(DateString
, TempString
);
522 TuiDrawText(UiScreenWidth
-strlen(DateString
)-2, 1, DateString
, ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
524 // Get the hour and change from 24-hour mode to 12-hour
534 _itoa(Hour
, TempString
, 10);
535 strcpy(TimeString
, " ");
536 strcat(TimeString
, TempString
);
537 strcat(TimeString
, ":");
538 _itoa(Minute
, TempString
, 10);
541 strcat(TimeString
, "0");
543 strcat(TimeString
, TempString
);
544 strcat(TimeString
, ":");
545 _itoa(Second
, TempString
, 10);
548 strcat(TimeString
, "0");
550 strcat(TimeString
, TempString
);
553 strcat(TimeString
, " PM");
557 strcat(TimeString
, " AM");
561 TuiDrawText(UiScreenWidth
-strlen(TimeString
)-2, 2, TimeString
, ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
564 VOID
TuiSaveScreen(PUCHAR Buffer
)
566 PUCHAR ScreenMemory
= (PUCHAR
)TextVideoBuffer
;
569 for (i
=0; i
< (UiScreenWidth
* UiScreenHeight
* 2); i
++)
571 Buffer
[i
] = ScreenMemory
[i
];
575 VOID
TuiRestoreScreen(PUCHAR Buffer
)
577 PUCHAR ScreenMemory
= (PUCHAR
)TextVideoBuffer
;
580 for (i
=0; i
< (UiScreenWidth
* UiScreenHeight
* 2); i
++)
582 ScreenMemory
[i
] = Buffer
[i
];
586 VOID
TuiMessageBox(PCSTR MessageText
)
590 // Save the screen contents
591 ScreenBuffer
= MmAllocateMemory(UiScreenWidth
* UiScreenHeight
* 2);
592 TuiSaveScreen(ScreenBuffer
);
594 // Display the message box
595 TuiMessageBoxCritical(MessageText
);
597 // Restore the screen contents
598 TuiRestoreScreen(ScreenBuffer
);
599 MmFreeMemory(ScreenBuffer
);
602 VOID
TuiMessageBoxCritical(PCSTR MessageText
)
605 unsigned int height
= 1;
614 for (i
=0; i
<strlen(MessageText
); i
++)
616 if (MessageText
[i
] == '\n')
621 for (i
=0,j
=0,k
=0; i
<height
; i
++)
623 while ((MessageText
[j
] != '\n') && (MessageText
[j
] != 0))
636 // Calculate box area
637 x1
= (UiScreenWidth
- (width
+2))/2;
639 y1
= ((UiScreenHeight
- height
- 2)/2) + 1;
640 y2
= y1
+ height
+ 4;
643 TuiDrawBox(x1
, y1
, x2
, y2
, D_VERT
, D_HORZ
, TRUE
, TRUE
, ATTR(UiMessageBoxFgColor
, UiMessageBoxBgColor
));
646 for (i
=0,j
=0; i
<strlen(MessageText
)+1; i
++)
648 if ((MessageText
[i
] == '\n') || (MessageText
[i
] == 0))
652 UiDrawText(x1
+2, y1
+1+curline
, temp
, ATTR(UiMessageBoxFgColor
, UiMessageBoxBgColor
));
656 temp
[j
++] = MessageText
[i
];
660 strcpy(temp
, " OK ");
661 UiDrawText(x1
+((x2
-x1
)/2)-3, y2
-2, temp
, ATTR(COLOR_BLACK
, COLOR_GRAY
));
664 UiDrawStatusText("Press ENTER to continue");
666 VideoCopyOffScreenBufferToVRAM();
672 key
= MachConsGetCh();
673 if(key
== KEY_EXTENDED
)
674 key
= MachConsGetCh();
678 else if(key
== KEY_SPACE
)
680 else if(key
== KEY_ESC
)
686 VideoCopyOffScreenBufferToVRAM();
692 VOID
TuiDrawProgressBarCenter(ULONG Position
, ULONG Range
, PCHAR ProgressText
)
694 ULONG Left
, Top
, Right
, Bottom
;
695 ULONG Width
= 50; // Allow for 50 "bars"
699 // Is this the minimal UI?
704 // Use alternate settings
708 Right
= Left
+ Width
;
709 Top
= UiScreenHeight
- Height
- 4;
710 Bottom
= Top
+ Height
+ 1;
714 Left
= (UiScreenWidth
- Width
- 4) / 2;
715 Right
= Left
+ Width
+ 3;
716 Top
= (UiScreenHeight
- Height
- 2) / 2;
720 Bottom
= Top
+ Height
+ 1;
722 TuiDrawProgressBar(Left
, Top
, Right
, Bottom
, Position
, Range
, ProgressText
);
725 VOID
TuiDrawProgressBar(ULONG Left
, ULONG Top
, ULONG Right
, ULONG Bottom
, ULONG Position
, ULONG Range
, PCHAR ProgressText
)
728 ULONG ProgressBarWidth
= (Right
- Left
) - 3;
730 // First make sure the progress bar text fits
731 UiTruncateStringEllipsis(ProgressText
, ProgressBarWidth
- 4);
733 if (Position
> Range
)
739 // Minimal UI has no box, and only generic loading text
744 TuiDrawBox(Left
, Top
, Right
, Bottom
, VERT
, HORZ
, TRUE
, TRUE
, ATTR(UiMenuFgColor
, UiMenuBgColor
));
747 // Draw the "Loading..." text
749 TuiDrawCenteredText(Left
+ 2, Top
+ 2, Right
- 2, Top
+ 2, ProgressText
, ATTR(UiTextColor
, UiMenuBgColor
));
754 // Draw the "Loading..." text
756 TuiDrawCenteredText(Left
+ 2, Top
+ 1, Right
- 2, Top
+ 1, "ReactOS is loading files...", ATTR(7, 0));
759 // Draw the percent complete
760 for (i
=0; i
<(Position
*ProgressBarWidth
)/Range
; i
++)
762 TuiDrawText(Left
+2+i
, Top
+2, "\xDB", ATTR(UiTextColor
, UiMenuBgColor
));
765 // Draw the shadow for non-minimal UI
768 for (; i
<ProgressBarWidth
; i
++)
770 TuiDrawText(Left
+2+i
, Top
+2, "\xB2", ATTR(UiTextColor
, UiMenuBgColor
));
775 VideoCopyOffScreenBufferToVRAM();
778 UCHAR
TuiTextToColor(PCSTR ColorText
)
780 if (_stricmp(ColorText
, "Black") == 0)
782 else if (_stricmp(ColorText
, "Blue") == 0)
784 else if (_stricmp(ColorText
, "Green") == 0)
786 else if (_stricmp(ColorText
, "Cyan") == 0)
788 else if (_stricmp(ColorText
, "Red") == 0)
790 else if (_stricmp(ColorText
, "Magenta") == 0)
791 return COLOR_MAGENTA
;
792 else if (_stricmp(ColorText
, "Brown") == 0)
794 else if (_stricmp(ColorText
, "Gray") == 0)
796 else if (_stricmp(ColorText
, "DarkGray") == 0)
797 return COLOR_DARKGRAY
;
798 else if (_stricmp(ColorText
, "LightBlue") == 0)
799 return COLOR_LIGHTBLUE
;
800 else if (_stricmp(ColorText
, "LightGreen") == 0)
801 return COLOR_LIGHTGREEN
;
802 else if (_stricmp(ColorText
, "LightCyan") == 0)
803 return COLOR_LIGHTCYAN
;
804 else if (_stricmp(ColorText
, "LightRed") == 0)
805 return COLOR_LIGHTRED
;
806 else if (_stricmp(ColorText
, "LightMagenta") == 0)
807 return COLOR_LIGHTMAGENTA
;
808 else if (_stricmp(ColorText
, "Yellow") == 0)
810 else if (_stricmp(ColorText
, "White") == 0)
816 UCHAR
TuiTextToFillStyle(PCSTR FillStyleText
)
818 if (_stricmp(FillStyleText
, "Light") == 0)
822 else if (_stricmp(FillStyleText
, "Medium") == 0)
826 else if (_stricmp(FillStyleText
, "Dark") == 0)
834 VOID
TuiFadeInBackdrop(VOID
)
836 PPALETTE_ENTRY TuiFadePalette
= NULL
;
838 if (UiUseSpecialEffects
&& ! MachVideoIsPaletteFixed())
840 TuiFadePalette
= (PPALETTE_ENTRY
)MmAllocateMemory(sizeof(PALETTE_ENTRY
) * 64);
842 if (TuiFadePalette
!= NULL
)
844 VideoSavePaletteState(TuiFadePalette
, 64);
845 VideoSetAllColorsToBlack(64);
849 // Draw the backdrop and title box
852 if (UiUseSpecialEffects
&& ! MachVideoIsPaletteFixed() && TuiFadePalette
!= NULL
)
854 VideoFadeIn(TuiFadePalette
, 64);
855 MmFreeMemory(TuiFadePalette
);
859 VOID
TuiFadeOut(VOID
)
861 PPALETTE_ENTRY TuiFadePalette
= NULL
;
863 if (UiUseSpecialEffects
&& ! MachVideoIsPaletteFixed())
865 TuiFadePalette
= (PPALETTE_ENTRY
)MmAllocateMemory(sizeof(PALETTE_ENTRY
) * 64);
867 if (TuiFadePalette
!= NULL
)
869 VideoSavePaletteState(TuiFadePalette
, 64);
873 if (UiUseSpecialEffects
&& ! MachVideoIsPaletteFixed() && TuiFadePalette
!= NULL
)
878 MachVideoSetDisplayMode(NULL
, FALSE
);
880 if (UiUseSpecialEffects
&& ! MachVideoIsPaletteFixed() && TuiFadePalette
!= NULL
)
882 VideoRestorePaletteState(TuiFadePalette
, 64);
883 MmFreeMemory(TuiFadePalette
);
888 BOOLEAN
TuiEditBox(PCSTR MessageText
, PCHAR EditTextBuffer
, ULONG Length
)
891 unsigned int height
= 1;
899 ULONG EditBoxStartX
, EditBoxEndX
;
901 unsigned int EditBoxTextCount
;
902 int EditBoxTextDisplayIndex
;
906 // Save the screen contents
907 ScreenBuffer
= MmAllocateMemory(UiScreenWidth
* UiScreenHeight
* 2);
908 TuiSaveScreen(ScreenBuffer
);
911 for (i
=0; i
<strlen(MessageText
); i
++)
913 if (MessageText
[i
] == '\n')
918 for (i
=0,j
=0,k
=0; i
<height
; i
++)
920 while ((MessageText
[j
] != '\n') && (MessageText
[j
] != 0))
933 // Calculate box area
934 x1
= (UiScreenWidth
- (width
+2))/2;
936 y1
= ((UiScreenHeight
- height
- 2)/2) + 1;
937 y2
= y1
+ height
+ 4;
940 TuiDrawBox(x1
, y1
, x2
, y2
, D_VERT
, D_HORZ
, TRUE
, TRUE
, ATTR(UiMessageBoxFgColor
, UiMessageBoxBgColor
));
943 for (i
=0,j
=0; i
<strlen(MessageText
)+1; i
++)
945 if ((MessageText
[i
] == '\n') || (MessageText
[i
] == 0))
949 UiDrawText(x1
+2, y1
+1+curline
, temp
, ATTR(UiMessageBoxFgColor
, UiMessageBoxBgColor
));
953 temp
[j
++] = MessageText
[i
];
956 EditBoxTextCount
= 0;
957 EditBoxLine
= y2
- 2;
958 EditBoxStartX
= x1
+ 3;
959 EditBoxEndX
= x2
- 3;
960 UiFillArea(EditBoxStartX
, EditBoxLine
, EditBoxEndX
, EditBoxLine
, ' ', ATTR(UiEditBoxTextColor
, UiEditBoxBgColor
));
963 EditBoxCursorX
= EditBoxStartX
;
964 MachVideoSetTextCursorPosition(EditBoxCursorX
, EditBoxLine
);
965 MachVideoHideShowTextCursor(TRUE
);
968 UiDrawStatusText("Press ENTER to continue, or ESC to cancel");
970 VideoCopyOffScreenBufferToVRAM();
976 key
= MachConsGetCh();
977 if(key
== KEY_EXTENDED
)
979 key
= MachConsGetCh();
987 else if(key
== KEY_ESC
)
992 else if (key
== KEY_BACKSPACE
) // Remove a character
994 if (EditBoxTextCount
)
997 EditTextBuffer
[EditBoxTextCount
] = 0;
1004 else // Add this key to the buffer
1006 if (EditBoxTextCount
< Length
- 1)
1008 EditTextBuffer
[EditBoxTextCount
] = key
;
1010 EditTextBuffer
[EditBoxTextCount
] = 0;
1019 // Draw the edit box background
1020 UiFillArea(EditBoxStartX
, EditBoxLine
, EditBoxEndX
, EditBoxLine
, ' ', ATTR(UiEditBoxTextColor
, UiEditBoxBgColor
));
1023 if (EditBoxTextCount
> (EditBoxEndX
- EditBoxStartX
))
1025 EditBoxTextDisplayIndex
= EditBoxTextCount
- (EditBoxEndX
- EditBoxStartX
);
1026 EditBoxCursorX
= EditBoxEndX
;
1030 EditBoxTextDisplayIndex
= 0;
1031 EditBoxCursorX
= EditBoxStartX
+ EditBoxTextCount
;
1033 UiDrawText(EditBoxStartX
, EditBoxLine
, &EditTextBuffer
[EditBoxTextDisplayIndex
], ATTR(UiEditBoxTextColor
, UiEditBoxBgColor
));
1036 MachVideoSetTextCursorPosition(EditBoxCursorX
, EditBoxLine
);
1038 TuiUpdateDateTime();
1040 VideoCopyOffScreenBufferToVRAM();
1043 // Hide the cursor again
1044 MachVideoHideShowTextCursor(FALSE
);
1046 // Restore the screen contents
1047 TuiRestoreScreen(ScreenBuffer
);
1048 MmFreeMemory(ScreenBuffer
);