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 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.
22 #define TAG_TUI_SCREENBUFFER 'SiuT'
23 #define TAG_TAG_TUI_PALETTE 'PiuT'
25 PVOID TextVideoBuffer
= NULL
;
29 * Prints formatted text to the screen
31 int TuiPrintf(const char *Format
, ...)
39 Length
= _vsnprintf(Buffer
, sizeof(Buffer
), Format
, ap
);
42 if (Length
== -1) Length
= sizeof(Buffer
);
44 for (i
= 0; i
< Length
; i
++)
46 MachConsPutChar(Buffer
[i
]);
52 BOOLEAN
TuiInitialize(VOID
)
54 MachVideoHideShowTextCursor(FALSE
);
55 MachVideoSetTextCursorPosition(0, 0);
56 MachVideoClearScreen(ATTR(COLOR_GRAY
, COLOR_BLACK
));
58 TextVideoBuffer
= VideoAllocateOffScreenBuffer();
59 if (TextVideoBuffer
== NULL
)
67 VOID
TuiUnInitialize(VOID
)
69 if (UiUseSpecialEffects
)
75 MachVideoSetDisplayMode(NULL
, FALSE
);
78 MachVideoClearScreen(ATTR(COLOR_GRAY
, COLOR_BLACK
));
79 MachVideoSetTextCursorPosition(0, 0);
80 MachVideoHideShowTextCursor(TRUE
);
83 VOID
TuiDrawBackdrop(VOID
)
86 // Fill in the background (excluding title box & status bar)
89 TUI_TITLE_BOX_CHAR_HEIGHT
,
93 ATTR(UiBackdropFgColor
, UiBackdropBgColor
));
101 TUI_TITLE_BOX_CHAR_HEIGHT
- 1,
106 ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
113 GetFreeLoaderVersionString(),
114 ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
122 ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
126 ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
131 TuiDrawText(UiScreenWidth
- 16, 3, /*"F1 for Help"*/"F8 for Options", ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
136 TuiDrawText((UiScreenWidth
- (ULONG
)strlen(UiTitleBoxTitleText
)) / 2,
139 ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
142 // Update the date & time
146 VideoCopyOffScreenBufferToVRAM();
151 * This function assumes coordinates are zero-based
153 VOID
TuiFillArea(ULONG Left
, ULONG Top
, ULONG Right
, ULONG Bottom
, CHAR FillChar
, UCHAR Attr
/* Color Attributes */)
155 PUCHAR ScreenMemory
= (PUCHAR
)TextVideoBuffer
;
158 // Clip the area to the screen
159 if ((Left
>= UiScreenWidth
) || (Top
>= UiScreenHeight
))
163 if (Right
>= UiScreenWidth
)
165 Right
= UiScreenWidth
- 1;
167 if (Bottom
>= UiScreenHeight
)
169 Bottom
= UiScreenHeight
- 1;
172 // Loop through each line and fill it in
173 for (i
=Top
; i
<=Bottom
; i
++)
175 // Loop through each character (column) in the line and fill it in
176 for (j
=Left
; j
<=Right
; j
++)
178 ScreenMemory
[((i
*2)*UiScreenWidth
)+(j
*2)] = (UCHAR
)FillChar
;
179 ScreenMemory
[((i
*2)*UiScreenWidth
)+(j
*2)+1] = Attr
;
186 * This function assumes coordinates are zero-based
188 VOID
TuiDrawShadow(ULONG Left
, ULONG Top
, ULONG Right
, ULONG Bottom
)
190 PUCHAR ScreenMemory
= (PUCHAR
)TextVideoBuffer
;
193 // Shade the bottom of the area
194 if (Bottom
< (UiScreenHeight
- 1))
196 if (UiScreenHeight
< 34)
205 for (; Idx
<=Right
; Idx
++)
207 ScreenMemory
[(((Bottom
+1)*2)*UiScreenWidth
)+(Idx
*2)+1] = ATTR(COLOR_GRAY
, COLOR_BLACK
);
211 // Shade the right of the area
212 if (Right
< (UiScreenWidth
- 1))
214 for (Idx
=Top
+1; Idx
<=Bottom
; Idx
++)
216 ScreenMemory
[((Idx
*2)*UiScreenWidth
)+((Right
+1)*2)+1] = ATTR(COLOR_GRAY
, COLOR_BLACK
);
219 if (UiScreenHeight
< 34)
221 if ((Right
+ 1) < (UiScreenWidth
- 1))
223 for (Idx
=Top
+1; Idx
<=Bottom
; Idx
++)
225 ScreenMemory
[((Idx
*2)*UiScreenWidth
)+((Right
+2)*2)+1] = ATTR(COLOR_GRAY
, COLOR_BLACK
);
230 // Shade the bottom right corner
231 if ((Right
< (UiScreenWidth
- 1)) && (Bottom
< (UiScreenHeight
- 1)))
233 ScreenMemory
[(((Bottom
+1)*2)*UiScreenWidth
)+((Right
+1)*2)+1] = ATTR(COLOR_GRAY
, COLOR_BLACK
);
235 if (UiScreenHeight
< 34)
237 if (((Right
+ 1) < (UiScreenWidth
- 1)) && (Bottom
< (UiScreenHeight
- 1)))
239 ScreenMemory
[(((Bottom
+1)*2)*UiScreenWidth
)+((Right
+2)*2)+1] = ATTR(COLOR_GRAY
, COLOR_BLACK
);
246 * This function assumes coordinates are zero-based
248 VOID
TuiDrawBox(ULONG Left
, ULONG Top
, ULONG Right
, ULONG Bottom
, UCHAR VertStyle
, UCHAR HorzStyle
, BOOLEAN Fill
, BOOLEAN Shadow
, UCHAR Attr
)
250 UCHAR ULCorner
, URCorner
, LLCorner
, LRCorner
;
252 // Calculate the corner values
253 if (HorzStyle
== HORZ
)
255 if (VertStyle
== VERT
)
262 else // VertStyle == D_VERT
270 else // HorzStyle == D_HORZ
272 if (VertStyle
== VERT
)
279 else // VertStyle == D_VERT
288 // Fill in box background
291 TuiFillArea(Left
, Top
, Right
, Bottom
, ' ', Attr
);
295 TuiFillArea(Left
, Top
, Left
, Top
, ULCorner
, Attr
);
296 TuiFillArea(Right
, Top
, Right
, Top
, URCorner
, Attr
);
297 TuiFillArea(Left
, Bottom
, Left
, Bottom
, LLCorner
, Attr
);
298 TuiFillArea(Right
, Bottom
, Right
, Bottom
, LRCorner
, Attr
);
301 TuiFillArea(Left
, Top
+1, Left
, Bottom
-1, VertStyle
, Attr
);
303 TuiFillArea(Left
+1, Top
, Right
-1, Top
, HorzStyle
, Attr
);
304 // Fill in right line
305 TuiFillArea(Right
, Top
+1, Right
, Bottom
-1, VertStyle
, Attr
);
306 // Fill in bottom line
307 TuiFillArea(Left
+1, Bottom
, Right
-1, Bottom
, HorzStyle
, Attr
);
312 TuiDrawShadow(Left
, Top
, Right
, Bottom
);
318 * This function assumes coordinates are zero-based
320 VOID
TuiDrawText(ULONG X
, ULONG Y
, PCSTR Text
, UCHAR Attr
)
322 PUCHAR ScreenMemory
= (PUCHAR
)TextVideoBuffer
;
326 for (i
= X
, j
= 0; Text
[j
] && i
< UiScreenWidth
; i
++, j
++)
328 ScreenMemory
[((Y
*2)*UiScreenWidth
)+(i
*2)] = (UCHAR
)Text
[j
];
329 ScreenMemory
[((Y
*2)*UiScreenWidth
)+(i
*2)+1] = Attr
;
335 * This function assumes coordinates are zero-based.
336 * MaxNumChars is the maximum number of characters to display.
337 * If MaxNumChars == 0, then display the whole string.
339 VOID
TuiDrawText2(ULONG X
, ULONG Y
, ULONG MaxNumChars
, PCSTR Text
, UCHAR Attr
)
341 PUCHAR ScreenMemory
= (PUCHAR
)TextVideoBuffer
;
345 for (i
= X
, j
= 0; Text
[j
] && i
< UiScreenWidth
&& (MaxNumChars
> 0 ? j
< MaxNumChars
: TRUE
); i
++, j
++)
347 ScreenMemory
[((Y
*2)*UiScreenWidth
)+(i
*2)] = (UCHAR
)Text
[j
];
348 ScreenMemory
[((Y
*2)*UiScreenWidth
)+(i
*2)+1] = Attr
;
352 VOID
TuiDrawCenteredText(ULONG Left
, ULONG Top
, ULONG Right
, ULONG Bottom
, PCSTR TextString
, UCHAR Attr
)
357 ULONG LineBreakCount
;
366 TextLength
= strlen(TextString
);
368 // Count the new lines and the box width
372 for (Index
=0; Index
<TextLength
; Index
++)
374 if (TextString
[Index
] == '\n')
381 if ((Index
- LastIndex
) > BoxWidth
)
383 BoxWidth
= (ULONG
)(Index
- LastIndex
);
388 BoxHeight
= LineBreakCount
+ 1;
390 RealLeft
= (((Right
- Left
) - BoxWidth
) / 2) + Left
;
391 RealTop
= (((Bottom
- Top
) - BoxHeight
) / 2) + Top
;
394 for (Index
=0; Index
<TextLength
; Index
++)
396 if (TextString
[Index
] == '\n')
403 X
= (ULONG
)(RealLeft
+ LastIndex
);
406 Temp
[0] = TextString
[Index
];
408 TuiDrawText(X
, Y
, Temp
, Attr
);
413 VOID
TuiDrawStatusText(PCSTR StatusText
)
417 TuiDrawText(0, UiScreenHeight
-1, " ", ATTR(UiStatusBarFgColor
, UiStatusBarBgColor
));
418 TuiDrawText(1, UiScreenHeight
-1, StatusText
, ATTR(UiStatusBarFgColor
, UiStatusBarBgColor
));
420 for (i
=strlen(StatusText
)+1; i
<UiScreenWidth
; i
++)
422 TuiDrawText((ULONG
)i
, UiScreenHeight
-1, " ", ATTR(UiStatusBarFgColor
, UiStatusBarBgColor
));
425 VideoCopyOffScreenBufferToVRAM();
428 VOID
TuiUpdateDateTime(VOID
)
434 BOOLEAN PMHour
= FALSE
;
436 /* Don't draw the time if this has been disabled */
437 if (!UiDrawTime
) return;
439 TimeInfo
= ArcGetTime();
440 if (TimeInfo
->Year
< 1 || 9999 < TimeInfo
->Year
||
441 TimeInfo
->Month
< 1 || 12 < TimeInfo
->Month
||
442 TimeInfo
->Day
< 1 || 31 < TimeInfo
->Day
||
443 23 < TimeInfo
->Hour
||
444 59 < TimeInfo
->Minute
||
445 59 < TimeInfo
->Second
)
447 /* This happens on QEmu sometimes. We just skip updating */
450 // Get the month name
451 strcpy(DateString
, UiMonthNames
[TimeInfo
->Month
- 1]);
453 _itoa(TimeInfo
->Day
, TempString
, 10);
454 // Get the day postfix
455 if (1 == TimeInfo
->Day
|| 21 == TimeInfo
->Day
|| 31 == TimeInfo
->Day
)
457 strcat(TempString
, "st");
459 else if (2 == TimeInfo
->Day
|| 22 == TimeInfo
->Day
)
461 strcat(TempString
, "nd");
463 else if (3 == TimeInfo
->Day
|| 23 == TimeInfo
->Day
)
465 strcat(TempString
, "rd");
469 strcat(TempString
, "th");
472 // Add the day to the date
473 strcat(DateString
, TempString
);
474 strcat(DateString
, " ");
476 // Get the year and add it to the date
477 _itoa(TimeInfo
->Year
, TempString
, 10);
478 strcat(DateString
, TempString
);
481 TuiDrawText(UiScreenWidth
-(ULONG
)strlen(DateString
)-2, 1, DateString
, ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
483 // Get the hour and change from 24-hour mode to 12-hour
484 if (TimeInfo
->Hour
> 12)
486 TimeInfo
->Hour
-= 12;
489 if (TimeInfo
->Hour
== 0)
493 _itoa(TimeInfo
->Hour
, TempString
, 10);
494 strcpy(TimeString
, " ");
495 strcat(TimeString
, TempString
);
496 strcat(TimeString
, ":");
497 _itoa(TimeInfo
->Minute
, TempString
, 10);
498 if (TimeInfo
->Minute
< 10)
500 strcat(TimeString
, "0");
502 strcat(TimeString
, TempString
);
503 strcat(TimeString
, ":");
504 _itoa(TimeInfo
->Second
, TempString
, 10);
505 if (TimeInfo
->Second
< 10)
507 strcat(TimeString
, "0");
509 strcat(TimeString
, TempString
);
512 strcat(TimeString
, " PM");
516 strcat(TimeString
, " AM");
520 TuiDrawText(UiScreenWidth
-(ULONG
)strlen(TimeString
)-2, 2, TimeString
, ATTR(UiTitleBoxFgColor
, UiTitleBoxBgColor
));
523 VOID
TuiSaveScreen(PUCHAR Buffer
)
525 PUCHAR ScreenMemory
= (PUCHAR
)TextVideoBuffer
;
528 for (i
=0; i
< (UiScreenWidth
* UiScreenHeight
* 2); i
++)
530 Buffer
[i
] = ScreenMemory
[i
];
534 VOID
TuiRestoreScreen(PUCHAR Buffer
)
536 PUCHAR ScreenMemory
= (PUCHAR
)TextVideoBuffer
;
539 for (i
=0; i
< (UiScreenWidth
* UiScreenHeight
* 2); i
++)
541 ScreenMemory
[i
] = Buffer
[i
];
545 VOID
TuiMessageBox(PCSTR MessageText
)
549 // Save the screen contents
550 ScreenBuffer
= FrLdrTempAlloc(UiScreenWidth
* UiScreenHeight
* 2,
551 TAG_TUI_SCREENBUFFER
);
552 TuiSaveScreen(ScreenBuffer
);
554 // Display the message box
555 TuiMessageBoxCritical(MessageText
);
557 // Restore the screen contents
558 TuiRestoreScreen(ScreenBuffer
);
559 FrLdrTempFree(ScreenBuffer
, TAG_TUI_SCREENBUFFER
);
562 VOID
TuiMessageBoxCritical(PCSTR MessageText
)
565 unsigned int height
= 1;
574 for (i
=0; i
<strlen(MessageText
); i
++)
576 if (MessageText
[i
] == '\n')
581 for (i
=0,j
=0,k
=0; i
<height
; i
++)
583 while ((MessageText
[j
] != '\n') && (MessageText
[j
] != 0))
596 // Calculate box area
597 x1
= (UiScreenWidth
- (width
+2))/2;
599 y1
= ((UiScreenHeight
- height
- 2)/2) + 1;
600 y2
= y1
+ height
+ 4;
603 TuiDrawBox(x1
, y1
, x2
, y2
, D_VERT
, D_HORZ
, TRUE
, TRUE
, ATTR(UiMessageBoxFgColor
, UiMessageBoxBgColor
));
606 for (i
=0,j
=0; i
<strlen(MessageText
)+1; i
++)
608 if ((MessageText
[i
] == '\n') || (MessageText
[i
] == 0))
612 UiDrawText(x1
+2, y1
+1+curline
, temp
, ATTR(UiMessageBoxFgColor
, UiMessageBoxBgColor
));
616 temp
[j
++] = MessageText
[i
];
620 strcpy(temp
, " OK ");
621 UiDrawText(x1
+((x2
-x1
)/2)-3, y2
-2, temp
, ATTR(COLOR_BLACK
, COLOR_GRAY
));
624 UiDrawStatusText("Press ENTER to continue");
626 VideoCopyOffScreenBufferToVRAM();
632 key
= MachConsGetCh();
633 if (key
== KEY_EXTENDED
)
634 key
= MachConsGetCh();
636 if ((key
== KEY_ENTER
) || (key
== KEY_SPACE
) || (key
== KEY_ESC
))
642 VideoCopyOffScreenBufferToVRAM();
648 VOID
TuiDrawProgressBarCenter(ULONG Position
, ULONG Range
, PCHAR ProgressText
)
650 ULONG Left
, Top
, Right
, Bottom
;
651 ULONG Width
= 50; // Allow for 50 "bars"
654 Left
= (UiScreenWidth
- Width
- 4) / 2;
655 Right
= Left
+ Width
+ 3;
656 Top
= (UiScreenHeight
- Height
- 2) / 2;
658 Bottom
= Top
+ Height
+ 1;
660 TuiDrawProgressBar(Left
, Top
, Right
, Bottom
, Position
, Range
, ProgressText
);
663 VOID
TuiDrawProgressBar(ULONG Left
, ULONG Top
, ULONG Right
, ULONG Bottom
, ULONG Position
, ULONG Range
, PCHAR ProgressText
)
666 ULONG ProgressBarWidth
= (Right
- Left
) - 3;
668 // First make sure the progress bar text fits
669 UiTruncateStringEllipsis(ProgressText
, ProgressBarWidth
- 4);
671 if (Position
> Range
)
677 TuiDrawBox(Left
, Top
, Right
, Bottom
, VERT
, HORZ
, TRUE
, TRUE
, ATTR(UiMenuFgColor
, UiMenuBgColor
));
680 // Draw the "Loading..." text
682 TuiDrawCenteredText(Left
+ 2, Top
+ 2, Right
- 2, Top
+ 2, ProgressText
, ATTR(UiTextColor
, UiMenuBgColor
));
684 // Draw the percent complete
685 for (i
=0; i
<(Position
*ProgressBarWidth
)/Range
; i
++)
687 TuiDrawText(Left
+2+i
, Top
+2, "\xDB", ATTR(UiTextColor
, UiMenuBgColor
));
691 for (; i
<ProgressBarWidth
; i
++)
693 TuiDrawText(Left
+2+i
, Top
+2, "\xB2", ATTR(UiTextColor
, UiMenuBgColor
));
697 VideoCopyOffScreenBufferToVRAM();
700 UCHAR
TuiTextToColor(PCSTR ColorText
)
708 {"Black" , COLOR_BLACK
},
709 {"Blue" , COLOR_BLUE
},
710 {"Green" , COLOR_GREEN
},
711 {"Cyan" , COLOR_CYAN
},
712 {"Red" , COLOR_RED
},
713 {"Magenta", COLOR_MAGENTA
},
714 {"Brown" , COLOR_BROWN
},
715 {"Gray" , COLOR_GRAY
},
716 {"DarkGray" , COLOR_DARKGRAY
},
717 {"LightBlue" , COLOR_LIGHTBLUE
},
718 {"LightGreen" , COLOR_LIGHTGREEN
},
719 {"LightCyan" , COLOR_LIGHTCYAN
},
720 {"LightRed" , COLOR_LIGHTRED
},
721 {"LightMagenta", COLOR_LIGHTMAGENTA
},
722 {"Yellow" , COLOR_YELLOW
},
723 {"White" , COLOR_WHITE
},
727 for (i
= 0; i
< sizeof(Colors
)/sizeof(Colors
[0]); ++i
)
729 if (_stricmp(ColorText
, Colors
[i
].ColorName
) == 0)
730 return Colors
[i
].ColorValue
;
736 UCHAR
TuiTextToFillStyle(PCSTR FillStyleText
)
741 UCHAR FillStyleValue
;
744 {"Light" , LIGHT_FILL
},
745 {"Medium", MEDIUM_FILL
},
746 {"Dark" , DARK_FILL
},
750 for (i
= 0; i
< sizeof(FillStyles
)/sizeof(FillStyles
[0]); ++i
)
752 if (_stricmp(FillStyleText
, FillStyles
[i
].FillStyleName
) == 0)
753 return FillStyles
[i
].FillStyleValue
;
759 VOID
TuiFadeInBackdrop(VOID
)
761 PPALETTE_ENTRY TuiFadePalette
= NULL
;
763 if (UiUseSpecialEffects
&& ! MachVideoIsPaletteFixed())
765 TuiFadePalette
= (PPALETTE_ENTRY
)FrLdrTempAlloc(sizeof(PALETTE_ENTRY
) * 64,
766 TAG_TAG_TUI_PALETTE
);
768 if (TuiFadePalette
!= NULL
)
770 VideoSavePaletteState(TuiFadePalette
, 64);
771 VideoSetAllColorsToBlack(64);
775 // Draw the backdrop and title box
778 if (UiUseSpecialEffects
&& ! MachVideoIsPaletteFixed() && TuiFadePalette
!= NULL
)
780 VideoFadeIn(TuiFadePalette
, 64);
781 FrLdrTempFree(TuiFadePalette
, TAG_TAG_TUI_PALETTE
);
785 VOID
TuiFadeOut(VOID
)
787 PPALETTE_ENTRY TuiFadePalette
= NULL
;
789 if (UiUseSpecialEffects
&& ! MachVideoIsPaletteFixed())
791 TuiFadePalette
= (PPALETTE_ENTRY
)FrLdrTempAlloc(sizeof(PALETTE_ENTRY
) * 64,
792 TAG_TAG_TUI_PALETTE
);
794 if (TuiFadePalette
!= NULL
)
796 VideoSavePaletteState(TuiFadePalette
, 64);
800 if (UiUseSpecialEffects
&& ! MachVideoIsPaletteFixed() && TuiFadePalette
!= NULL
)
805 MachVideoSetDisplayMode(NULL
, FALSE
);
807 if (UiUseSpecialEffects
&& ! MachVideoIsPaletteFixed() && TuiFadePalette
!= NULL
)
809 VideoRestorePaletteState(TuiFadePalette
, 64);
810 FrLdrTempFree(TuiFadePalette
, TAG_TAG_TUI_PALETTE
);
815 BOOLEAN
TuiEditBox(PCSTR MessageText
, PCHAR EditTextBuffer
, ULONG Length
)
827 ULONG EditBoxStartX
, EditBoxEndX
;
829 ULONG EditBoxTextLength
, EditBoxTextPosition
;
830 INT EditBoxTextDisplayIndex
;
834 // Save the screen contents
835 ScreenBuffer
= FrLdrTempAlloc(UiScreenWidth
* UiScreenHeight
* 2,
836 TAG_TUI_SCREENBUFFER
);
837 TuiSaveScreen(ScreenBuffer
);
840 for (i
=0; i
<strlen(MessageText
); i
++)
842 if (MessageText
[i
] == '\n')
847 for (i
=0,j
=0,k
=0; i
<height
; i
++)
849 while ((MessageText
[j
] != '\n') && (MessageText
[j
] != 0))
862 // Calculate box area
863 x1
= (UiScreenWidth
- (width
+2))/2;
865 y1
= ((UiScreenHeight
- height
- 2)/2) + 1;
866 y2
= y1
+ height
+ 4;
869 TuiDrawBox(x1
, y1
, x2
, y2
, D_VERT
, D_HORZ
, TRUE
, TRUE
, ATTR(UiMessageBoxFgColor
, UiMessageBoxBgColor
));
872 for (i
=0,j
=0; i
<strlen(MessageText
)+1; i
++)
874 if ((MessageText
[i
] == '\n') || (MessageText
[i
] == 0))
878 UiDrawText(x1
+2, y1
+1+curline
, temp
, ATTR(UiMessageBoxFgColor
, UiMessageBoxBgColor
));
882 temp
[j
++] = MessageText
[i
];
885 EditBoxTextLength
= (ULONG
)strlen(EditTextBuffer
);
886 EditBoxTextLength
= min(EditBoxTextLength
, Length
- 1);
887 EditBoxTextPosition
= 0;
888 EditBoxLine
= y2
- 2;
889 EditBoxStartX
= x1
+ 3;
890 EditBoxEndX
= x2
- 3;
892 // Draw the edit box background and the text
893 UiFillArea(EditBoxStartX
, EditBoxLine
, EditBoxEndX
, EditBoxLine
, ' ', ATTR(UiEditBoxTextColor
, UiEditBoxBgColor
));
894 UiDrawText2(EditBoxStartX
, EditBoxLine
, EditBoxEndX
- EditBoxStartX
+ 1, EditTextBuffer
, ATTR(UiEditBoxTextColor
, UiEditBoxBgColor
));
897 EditBoxCursorX
= EditBoxStartX
;
898 MachVideoSetTextCursorPosition(EditBoxCursorX
, EditBoxLine
);
899 MachVideoHideShowTextCursor(TRUE
);
902 UiDrawStatusText("Press ENTER to continue, or ESC to cancel");
904 VideoCopyOffScreenBufferToVRAM();
907 // Enter the text. Please keep in mind that the default input mode
908 // of the edit boxes is in insertion mode, that is, you can insert
909 // text without erasing the existing one.
916 key
= MachConsGetCh();
917 if (key
== KEY_EXTENDED
)
920 key
= MachConsGetCh();
923 if (key
== KEY_ENTER
)
928 else if (key
== KEY_ESC
)
933 else if (key
== KEY_BACKSPACE
) // Remove a character
935 if ( (EditBoxTextLength
> 0) && (EditBoxTextPosition
> 0) &&
936 (EditBoxTextPosition
<= EditBoxTextLength
) )
938 EditBoxTextPosition
--;
939 memmove(EditTextBuffer
+ EditBoxTextPosition
,
940 EditTextBuffer
+ EditBoxTextPosition
+ 1,
941 EditBoxTextLength
- EditBoxTextPosition
);
943 EditTextBuffer
[EditBoxTextLength
] = 0;
950 else if (Extended
&& key
== KEY_DELETE
) // Remove a character
952 if ( (EditBoxTextLength
> 0) &&
953 (EditBoxTextPosition
< EditBoxTextLength
) )
955 memmove(EditTextBuffer
+ EditBoxTextPosition
,
956 EditTextBuffer
+ EditBoxTextPosition
+ 1,
957 EditBoxTextLength
- EditBoxTextPosition
);
959 EditTextBuffer
[EditBoxTextLength
] = 0;
966 else if (Extended
&& key
== KEY_HOME
) // Go to the start of the buffer
968 EditBoxTextPosition
= 0;
970 else if (Extended
&& key
== KEY_END
) // Go to the end of the buffer
972 EditBoxTextPosition
= EditBoxTextLength
;
974 else if (Extended
&& key
== KEY_RIGHT
) // Go right
976 if (EditBoxTextPosition
< EditBoxTextLength
)
977 EditBoxTextPosition
++;
981 else if (Extended
&& key
== KEY_LEFT
) // Go left
983 if (EditBoxTextPosition
> 0)
984 EditBoxTextPosition
--;
988 else if (!Extended
) // Add this key to the buffer
990 if ( (EditBoxTextLength
< Length
- 1) &&
991 (EditBoxTextPosition
< Length
- 1) )
993 memmove(EditTextBuffer
+ EditBoxTextPosition
+ 1,
994 EditTextBuffer
+ EditBoxTextPosition
,
995 EditBoxTextLength
- EditBoxTextPosition
);
996 EditTextBuffer
[EditBoxTextPosition
] = key
;
997 EditBoxTextPosition
++;
999 EditTextBuffer
[EditBoxTextLength
] = 0;
1012 // Draw the edit box background
1013 UiFillArea(EditBoxStartX
, EditBoxLine
, EditBoxEndX
, EditBoxLine
, ' ', ATTR(UiEditBoxTextColor
, UiEditBoxBgColor
));
1016 if (EditBoxTextPosition
> (EditBoxEndX
- EditBoxStartX
))
1018 EditBoxTextDisplayIndex
= EditBoxTextPosition
- (EditBoxEndX
- EditBoxStartX
);
1019 EditBoxCursorX
= EditBoxEndX
;
1023 EditBoxTextDisplayIndex
= 0;
1024 EditBoxCursorX
= EditBoxStartX
+ EditBoxTextPosition
;
1026 UiDrawText2(EditBoxStartX
, EditBoxLine
, EditBoxEndX
- EditBoxStartX
+ 1, &EditTextBuffer
[EditBoxTextDisplayIndex
], ATTR(UiEditBoxTextColor
, UiEditBoxBgColor
));
1029 MachVideoSetTextCursorPosition(EditBoxCursorX
, EditBoxLine
);
1031 TuiUpdateDateTime();
1033 VideoCopyOffScreenBufferToVRAM();
1038 // Hide the cursor again
1039 MachVideoHideShowTextCursor(FALSE
);
1041 // Restore the screen contents
1042 TuiRestoreScreen(ScreenBuffer
);
1043 FrLdrTempFree(ScreenBuffer
, TAG_TUI_SCREENBUFFER
);
1048 const UIVTBL TuiVtbl
=
1058 TuiDrawCenteredText
,
1062 TuiMessageBoxCritical
,
1063 TuiDrawProgressBarCenter
,