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