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