30e874041fa2d695558bea2a65dc1635b2337d31
[reactos.git] / reactos / boot / freeldr / freeldr / ui / ui.c
1 /*
2 * FreeLoader
3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
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 #ifndef _M_ARM
20 #include <freeldr.h>
21 #include <debug.h>
22 #include <reactos/buildno.h>
23
24 DBG_DEFAULT_CHANNEL(UI);
25
26 BOOLEAN UiMinimal = FALSE; // Tells us if we are using a minimal console-like UI
27
28 ULONG UiScreenWidth; // Screen Width
29 ULONG UiScreenHeight; // Screen Height
30
31 UCHAR UiStatusBarFgColor = COLOR_BLACK; // Status bar foreground color
32 UCHAR UiStatusBarBgColor = COLOR_CYAN; // Status bar background color
33 UCHAR UiBackdropFgColor = COLOR_WHITE; // Backdrop foreground color
34 UCHAR UiBackdropBgColor = COLOR_BLUE; // Backdrop background color
35 UCHAR UiBackdropFillStyle = MEDIUM_FILL; // Backdrop fill style
36 UCHAR UiTitleBoxFgColor = COLOR_WHITE; // Title box foreground color
37 UCHAR UiTitleBoxBgColor = COLOR_RED; // Title box background color
38 UCHAR UiMessageBoxFgColor = COLOR_WHITE; // Message box foreground color
39 UCHAR UiMessageBoxBgColor = COLOR_BLUE; // Message box background color
40 UCHAR UiMenuFgColor = COLOR_WHITE; // Menu foreground color
41 UCHAR UiMenuBgColor = COLOR_BLUE; // Menu background color
42 UCHAR UiTextColor = COLOR_YELLOW; // Normal text color
43 UCHAR UiSelectedTextColor = COLOR_BLACK; // Selected text color
44 UCHAR UiSelectedTextBgColor = COLOR_GRAY; // Selected text background color
45 UCHAR UiEditBoxTextColor = COLOR_WHITE; // Edit box text color
46 UCHAR UiEditBoxBgColor = COLOR_BLACK; // Edit box text background color
47
48 CHAR UiTitleBoxTitleText[260] = "Boot Menu"; // Title box's title text
49
50 BOOLEAN UiUseSpecialEffects = FALSE; // Tells us if we should use fade effects
51 BOOLEAN UiDrawTime = TRUE; // Tells us if we should draw the time
52 BOOLEAN UiCenterMenu = TRUE; // Tells us if we should use a centered or left-aligned menu
53 BOOLEAN UiMenuBox = TRUE; // Tells us if we shuld draw a box around the menu
54 CHAR UiTimeText[260] = "[Time Remaining: ] ";
55
56 const CHAR UiMonthNames[12][15] = { "January ", "February ", "March ", "April ", "May ", "June ", "July ", "August ", "September ", "October ", "November ", "December " };
57
58 UIVTBL UiVtbl =
59 {
60 NoUiInitialize,
61 NoUiUnInitialize,
62 NoUiDrawBackdrop,
63 NoUiFillArea,
64 NoUiDrawShadow,
65 NoUiDrawBox,
66 NoUiDrawText,
67 NoUiDrawCenteredText,
68 NoUiDrawStatusText,
69 NoUiUpdateDateTime,
70 NoUiMessageBox,
71 NoUiMessageBoxCritical,
72 NoUiDrawProgressBarCenter,
73 NoUiDrawProgressBar,
74 NoUiEditBox,
75 NoUiTextToColor,
76 NoUiTextToFillStyle,
77 NoUiFadeInBackdrop,
78 NoUiFadeOut,
79 NoUiDisplayMenu,
80 NoUiDrawMenu,
81 };
82
83 BOOLEAN UiInitialize(BOOLEAN ShowGui)
84 {
85 VIDEODISPLAYMODE UiDisplayMode; // Tells us if we are in text or graphics mode
86 ULONG_PTR SectionId;
87 CHAR DisplayModeText[260];
88 CHAR SettingText[260];
89 ULONG Depth;
90
91 if (!ShowGui)
92 {
93 if (!UiVtbl.Initialize())
94 {
95 MachVideoSetDisplayMode(NULL, FALSE);
96 return FALSE;
97 }
98 return TRUE;
99 }
100
101 TRACE("Initializing User Interface.\n");
102 TRACE("Reading in UI settings from [Display] section.\n");
103
104 DisplayModeText[0] = '\0';
105 if (IniOpenSection("Display", &SectionId))
106 {
107 if (!IniReadSettingByName(SectionId, "DisplayMode", DisplayModeText, sizeof(DisplayModeText)))
108 {
109 DisplayModeText[0] = '\0';
110 }
111 if (IniReadSettingByName(SectionId, "MinimalUI", SettingText, sizeof(SettingText)))
112 {
113 UiMinimal = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
114 }
115 }
116
117 UiDisplayMode = MachVideoSetDisplayMode(DisplayModeText, TRUE);
118 MachVideoGetDisplaySize(&UiScreenWidth, &UiScreenHeight, &Depth);
119
120 if (VideoTextMode == UiDisplayMode)
121 UiVtbl = (UiMinimal ? MiniTuiVtbl : TuiVtbl);
122 else
123 UiVtbl = GuiVtbl;
124
125 if (!UiVtbl.Initialize())
126 {
127 MachVideoSetDisplayMode(NULL, FALSE);
128 return FALSE;
129 }
130
131 if (IniOpenSection("Display", &SectionId))
132 {
133 if (IniReadSettingByName(SectionId, "TitleText", SettingText, sizeof(SettingText)))
134 {
135 strcpy(UiTitleBoxTitleText, SettingText);
136 }
137 if (IniReadSettingByName(SectionId, "TimeText", SettingText, sizeof(SettingText)))
138 {
139 strcpy(UiTimeText, SettingText);
140 }
141 if (IniReadSettingByName(SectionId, "StatusBarColor", SettingText, sizeof(SettingText)))
142 {
143 UiStatusBarBgColor = UiTextToColor(SettingText);
144 }
145 if (IniReadSettingByName(SectionId, "StatusBarTextColor", SettingText, sizeof(SettingText)))
146 {
147 UiStatusBarFgColor = UiTextToColor(SettingText);
148 }
149 if (IniReadSettingByName(SectionId, "BackdropTextColor", SettingText, sizeof(SettingText)))
150 {
151 UiBackdropFgColor = UiTextToColor(SettingText);
152 }
153 if (IniReadSettingByName(SectionId, "BackdropColor", SettingText, sizeof(SettingText)))
154 {
155 UiBackdropBgColor = UiTextToColor(SettingText);
156 }
157 if (IniReadSettingByName(SectionId, "BackdropFillStyle", SettingText, sizeof(SettingText)))
158 {
159 UiBackdropFillStyle = UiTextToFillStyle(SettingText);
160 }
161 if (IniReadSettingByName(SectionId, "TitleBoxTextColor", SettingText, sizeof(SettingText)))
162 {
163 UiTitleBoxFgColor = UiTextToColor(SettingText);
164 }
165 if (IniReadSettingByName(SectionId, "TitleBoxColor", SettingText, sizeof(SettingText)))
166 {
167 UiTitleBoxBgColor = UiTextToColor(SettingText);
168 }
169 if (IniReadSettingByName(SectionId, "MessageBoxTextColor", SettingText, sizeof(SettingText)))
170 {
171 UiMessageBoxFgColor = UiTextToColor(SettingText);
172 }
173 if (IniReadSettingByName(SectionId, "MessageBoxColor", SettingText, sizeof(SettingText)))
174 {
175 UiMessageBoxBgColor = UiTextToColor(SettingText);
176 }
177 if (IniReadSettingByName(SectionId, "MenuTextColor", SettingText, sizeof(SettingText)))
178 {
179 UiMenuFgColor = UiTextToColor(SettingText);
180 }
181 if (IniReadSettingByName(SectionId, "MenuColor", SettingText, sizeof(SettingText)))
182 {
183 UiMenuBgColor = UiTextToColor(SettingText);
184 }
185 if (IniReadSettingByName(SectionId, "TextColor", SettingText, sizeof(SettingText)))
186 {
187 UiTextColor = UiTextToColor(SettingText);
188 }
189 if (IniReadSettingByName(SectionId, "SelectedTextColor", SettingText, sizeof(SettingText)))
190 {
191 UiSelectedTextColor = UiTextToColor(SettingText);
192 }
193 if (IniReadSettingByName(SectionId, "SelectedColor", SettingText, sizeof(SettingText)))
194 {
195 UiSelectedTextBgColor = UiTextToColor(SettingText);
196 }
197 if (IniReadSettingByName(SectionId, "EditBoxTextColor", SettingText, sizeof(SettingText)))
198 {
199 UiEditBoxTextColor = UiTextToColor(SettingText);
200 }
201 if (IniReadSettingByName(SectionId, "EditBoxColor", SettingText, sizeof(SettingText)))
202 {
203 UiEditBoxBgColor = UiTextToColor(SettingText);
204 }
205 if (IniReadSettingByName(SectionId, "SpecialEffects", SettingText, sizeof(SettingText)))
206 {
207 UiUseSpecialEffects = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
208 }
209 if (IniReadSettingByName(SectionId, "ShowTime", SettingText, sizeof(SettingText)))
210 {
211 UiDrawTime = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
212 }
213 if (IniReadSettingByName(SectionId, "MenuBox", SettingText, sizeof(SettingText)))
214 {
215 UiMenuBox = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
216 }
217 if (IniReadSettingByName(SectionId, "CenterMenu", SettingText, sizeof(SettingText)))
218 {
219 UiCenterMenu = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
220 }
221 }
222
223 // Draw the backdrop and fade it in if special effects are enabled
224 UiFadeInBackdrop();
225
226 TRACE("UiInitialize() returning TRUE.\n");
227 return TRUE;
228 }
229
230 VOID UiUnInitialize(PCSTR BootText)
231 {
232 UiDrawBackdrop();
233 UiDrawStatusText("Booting...");
234 UiInfoBox(BootText);
235
236 UiVtbl.UnInitialize();
237 }
238
239 VOID UiDrawBackdrop(VOID)
240 {
241 UiVtbl.DrawBackdrop();
242 }
243
244 VOID UiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, CHAR FillChar, UCHAR Attr /* Color Attributes */)
245 {
246 UiVtbl.FillArea(Left, Top, Right, Bottom, FillChar, Attr);
247 }
248
249 VOID UiDrawShadow(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom)
250 {
251 UiVtbl.DrawShadow(Left, Top, Right, Bottom);
252 }
253
254 VOID UiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyle, UCHAR HorzStyle, BOOLEAN Fill, BOOLEAN Shadow, UCHAR Attr)
255 {
256 UiVtbl.DrawBox(Left, Top, Right, Bottom, VertStyle, HorzStyle, Fill, Shadow, Attr);
257 }
258
259 VOID UiDrawText(ULONG X, ULONG Y, PCSTR Text, UCHAR Attr)
260 {
261 UiVtbl.DrawText(X, Y, Text, Attr);
262 }
263
264 VOID UiDrawCenteredText(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, PCSTR TextString, UCHAR Attr)
265 {
266 UiVtbl.DrawCenteredText(Left, Top, Right, Bottom, TextString, Attr);
267 }
268
269 VOID UiDrawStatusText(PCSTR StatusText)
270 {
271 UiVtbl.DrawStatusText(StatusText);
272 }
273
274 VOID UiUpdateDateTime(VOID)
275 {
276 UiVtbl.UpdateDateTime();
277 }
278
279 VOID UiInfoBox(PCSTR MessageText)
280 {
281 SIZE_T TextLength;
282 ULONG BoxWidth;
283 ULONG BoxHeight;
284 ULONG LineBreakCount;
285 SIZE_T Index;
286 SIZE_T LastIndex;
287 ULONG Left;
288 ULONG Top;
289 ULONG Right;
290 ULONG Bottom;
291
292 TextLength = strlen(MessageText);
293
294 // Count the new lines and the box width
295 LineBreakCount = 0;
296 BoxWidth = 0;
297 LastIndex = 0;
298 for (Index=0; Index<TextLength; Index++)
299 {
300 if (MessageText[Index] == '\n')
301 {
302 LastIndex = Index;
303 LineBreakCount++;
304 }
305 else
306 {
307 if ((Index - LastIndex) > BoxWidth)
308 {
309 BoxWidth = (ULONG)(Index - LastIndex);
310 }
311 }
312 }
313
314 // Calc the box width & height
315 BoxWidth += 6;
316 BoxHeight = LineBreakCount + 4;
317
318 // Calc the box coordinates
319 Left = (UiScreenWidth / 2) - (BoxWidth / 2);
320 Top =(UiScreenHeight / 2) - (BoxHeight / 2);
321 Right = (UiScreenWidth / 2) + (BoxWidth / 2);
322 Bottom = (UiScreenHeight / 2) + (BoxHeight / 2);
323
324 // Draw the box
325 UiDrawBox(Left,
326 Top,
327 Right,
328 Bottom,
329 VERT,
330 HORZ,
331 TRUE,
332 TRUE,
333 ATTR(UiMenuFgColor, UiMenuBgColor)
334 );
335
336 // Draw the text
337 UiDrawCenteredText(Left, Top, Right, Bottom, MessageText, ATTR(UiTextColor, UiMenuBgColor));
338 }
339
340 VOID UiMessageBox(PCSTR MessageText)
341 {
342 UiVtbl.MessageBox(MessageText);
343 }
344
345 VOID UiMessageBoxCritical(PCSTR MessageText)
346 {
347 UiVtbl.MessageBoxCritical(MessageText);
348 }
349
350 UCHAR UiTextToColor(PCSTR ColorText)
351 {
352 return UiVtbl.TextToColor(ColorText);
353 }
354
355 UCHAR UiTextToFillStyle(PCSTR FillStyleText)
356 {
357 return UiVtbl.TextToFillStyle(FillStyleText);
358 }
359
360 VOID UiDrawProgressBarCenter(ULONG Position, ULONG Range, PCHAR ProgressText)
361 {
362 UiVtbl.DrawProgressBarCenter(Position, Range, ProgressText);
363 }
364
365 VOID UiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG Position, ULONG Range, PCHAR ProgressText)
366 {
367 UiVtbl.DrawProgressBar(Left, Top, Right, Bottom, Position, Range, ProgressText);
368 }
369
370 VOID UiShowMessageBoxesInSection(PCSTR SectionName)
371 {
372 ULONG Idx;
373 CHAR SettingName[80];
374 CHAR SettingValue[80];
375 PCHAR MessageBoxText;
376 ULONG MessageBoxTextSize;
377 ULONG_PTR SectionId;
378
379 if (!IniOpenSection(SectionName, &SectionId))
380 {
381 return;
382 }
383
384 //
385 // Find all the message box settings and run them
386 //
387 for (Idx=0; Idx<IniGetNumSectionItems(SectionId); Idx++)
388 {
389 IniReadSettingByNumber(SectionId, Idx, SettingName, sizeof(SettingName), SettingValue, sizeof(SettingValue));
390
391 if (_stricmp(SettingName, "MessageBox") == 0)
392 {
393 // Get the real length of the MessageBox text
394 MessageBoxTextSize = IniGetSectionSettingValueSize(SectionId, Idx);
395
396 //if (MessageBoxTextSize > 0)
397 {
398 // Allocate enough memory to hold the text
399 MessageBoxText = MmHeapAlloc(MessageBoxTextSize);
400
401 if (MessageBoxText)
402 {
403 // Get the MessageBox text
404 IniReadSettingByNumber(SectionId, Idx, SettingName, sizeof(SettingName), MessageBoxText, MessageBoxTextSize);
405
406 // Fix it up
407 UiEscapeString(MessageBoxText);
408
409 // Display it
410 UiMessageBox(MessageBoxText);
411
412 // Free the memory
413 MmHeapFree(MessageBoxText);
414 }
415 }
416 }
417 }
418 }
419
420 VOID UiEscapeString(PCHAR String)
421 {
422 ULONG Idx;
423
424 for (Idx=0; Idx<strlen(String); Idx++)
425 {
426 // Escape the new line characters
427 if (String[Idx] == '\\' && String[Idx+1] == 'n')
428 {
429 // Escape the character
430 String[Idx] = '\n';
431
432 // Move the rest of the string up
433 strcpy(&String[Idx+1], &String[Idx+2]);
434 }
435 }
436 }
437
438 VOID UiTruncateStringEllipsis(PCHAR StringText, ULONG MaxChars)
439 {
440 if (strlen(StringText) > MaxChars)
441 {
442 strcpy(&StringText[MaxChars - 3], "...");
443 }
444 }
445
446 BOOLEAN UiDisplayMenu(PCSTR MenuTitle, PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOLEAN CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter)
447 {
448 return UiVtbl.DisplayMenu(MenuTitle, MenuItemList, MenuItemCount, DefaultMenuItem, MenuTimeOut, SelectedMenuItem, CanEscape, KeyPressFilter);
449 }
450
451 VOID UiFadeInBackdrop(VOID)
452 {
453 UiVtbl.FadeInBackdrop();
454 }
455
456 VOID UiFadeOut(VOID)
457 {
458 UiVtbl.FadeOut();
459 }
460
461 BOOLEAN UiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
462 {
463 return UiVtbl.EditBox(MessageText, EditTextBuffer, Length);
464 }
465
466
467 /* SETUP MODE *****************************************************************/
468
469 VOID SetupUiDrawBackdrop(VOID)
470 {
471 CHAR Underline[80];
472 SIZE_T Length;
473
474 // Draw the backdrop and fade it in if special effects are enabled
475 UiVtbl.FillArea(0, 0, UiScreenWidth - 1, UiScreenHeight - 2, 0,
476 ATTR(UiBackdropFgColor, UiBackdropBgColor));
477
478 Length = min( strlen("ReactOS " KERNEL_VERSION_STR " Setup"),
479 sizeof(Underline) - 1 );
480 memset(Underline, 0xcd, Length); // Underline title
481 Underline[Length] = '\0';
482
483 UiVtbl.DrawText(4, 1, "ReactOS " KERNEL_VERSION_STR " Setup", ATTR(COLOR_GRAY, UiBackdropBgColor));
484 UiVtbl.DrawText(4, 2, Underline, ATTR(COLOR_GRAY, UiBackdropBgColor));
485
486 // Update the screen buffer
487 VideoCopyOffScreenBufferToVRAM();
488 }
489
490 BOOLEAN SetupUiInitialize(VOID)
491 {
492 if (!UiMinimal)
493 {
494 ULONG Depth;
495
496 // Initialize the video
497 MachVideoSetDisplayMode(NULL, TRUE);
498 MachVideoGetDisplaySize(&UiScreenWidth, &UiScreenHeight, &Depth);
499
500 // Use Text UI with a modified backdrop and set display properties
501 UiVtbl = TuiVtbl;
502 UiVtbl.DrawBackdrop = SetupUiDrawBackdrop;
503
504 UiStatusBarFgColor = COLOR_BLACK;
505 UiStatusBarBgColor = COLOR_GRAY;
506 UiBackdropFgColor = COLOR_WHITE;
507 UiBackdropBgColor = COLOR_BLUE;
508 UiBackdropFillStyle = MEDIUM_FILL;
509 UiTitleBoxFgColor = COLOR_WHITE;
510 UiTitleBoxBgColor = COLOR_RED;
511 UiMessageBoxFgColor = COLOR_WHITE;
512 UiMessageBoxBgColor = COLOR_BLUE;
513 UiMenuFgColor = COLOR_WHITE;
514 UiMenuBgColor = COLOR_BLUE;
515 UiTextColor = COLOR_YELLOW;
516 UiSelectedTextColor = COLOR_BLACK;
517 UiSelectedTextBgColor = COLOR_GRAY;
518 UiEditBoxTextColor = COLOR_WHITE;
519 UiEditBoxBgColor = COLOR_BLACK;
520 UiUseSpecialEffects = FALSE;
521 UiDrawTime = FALSE;
522
523 UiVtbl.Initialize();
524
525 // Draw the backdrop
526 UiDrawBackdrop();
527 }
528
529 TRACE("SetupUiInitialize() returning TRUE.\n");
530
531 return TRUE;
532 }
533
534 #endif