[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
21 #include <freeldr.h>
22 #include <debug.h>
23
24 #define TAG_UI_TEXT 'xTiU'
25
26 DBG_DEFAULT_CHANNEL(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 NoUiDrawText2,
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 BOOLEAN UiMinimal = FALSE; // Tells us if we are using a minimal console-like UI
88 ULONG_PTR SectionId;
89 CHAR DisplayModeText[260];
90 CHAR SettingText[260];
91 ULONG Depth;
92
93 if (!ShowGui)
94 {
95 if (!UiVtbl.Initialize())
96 {
97 MachVideoSetDisplayMode(NULL, FALSE);
98 return FALSE;
99 }
100 return TRUE;
101 }
102
103 TRACE("Initializing User Interface.\n");
104 TRACE("Reading in UI settings from [Display] section.\n");
105
106 DisplayModeText[0] = '\0';
107 if (IniOpenSection("Display", &SectionId))
108 {
109 if (!IniReadSettingByName(SectionId, "DisplayMode", DisplayModeText, sizeof(DisplayModeText)))
110 {
111 DisplayModeText[0] = '\0';
112 }
113 if (IniReadSettingByName(SectionId, "MinimalUI", SettingText, sizeof(SettingText)))
114 {
115 UiMinimal = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
116 }
117 }
118
119 UiDisplayMode = MachVideoSetDisplayMode(DisplayModeText, TRUE);
120 MachVideoGetDisplaySize(&UiScreenWidth, &UiScreenHeight, &Depth);
121
122 if (VideoTextMode == UiDisplayMode)
123 UiVtbl = (UiMinimal ? MiniTuiVtbl : TuiVtbl);
124 else
125 UiVtbl = GuiVtbl;
126
127 if (!UiVtbl.Initialize())
128 {
129 MachVideoSetDisplayMode(NULL, FALSE);
130 return FALSE;
131 }
132
133 if (IniOpenSection("Display", &SectionId))
134 {
135 if (IniReadSettingByName(SectionId, "TitleText", SettingText, sizeof(SettingText)))
136 {
137 strcpy(UiTitleBoxTitleText, SettingText);
138 }
139 if (IniReadSettingByName(SectionId, "TimeText", SettingText, sizeof(SettingText)))
140 {
141 strcpy(UiTimeText, SettingText);
142 }
143 if (IniReadSettingByName(SectionId, "StatusBarColor", SettingText, sizeof(SettingText)))
144 {
145 UiStatusBarBgColor = UiTextToColor(SettingText);
146 }
147 if (IniReadSettingByName(SectionId, "StatusBarTextColor", SettingText, sizeof(SettingText)))
148 {
149 UiStatusBarFgColor = UiTextToColor(SettingText);
150 }
151 if (IniReadSettingByName(SectionId, "BackdropTextColor", SettingText, sizeof(SettingText)))
152 {
153 UiBackdropFgColor = UiTextToColor(SettingText);
154 }
155 if (IniReadSettingByName(SectionId, "BackdropColor", SettingText, sizeof(SettingText)))
156 {
157 UiBackdropBgColor = UiTextToColor(SettingText);
158 }
159 if (IniReadSettingByName(SectionId, "BackdropFillStyle", SettingText, sizeof(SettingText)))
160 {
161 UiBackdropFillStyle = UiTextToFillStyle(SettingText);
162 }
163 if (IniReadSettingByName(SectionId, "TitleBoxTextColor", SettingText, sizeof(SettingText)))
164 {
165 UiTitleBoxFgColor = UiTextToColor(SettingText);
166 }
167 if (IniReadSettingByName(SectionId, "TitleBoxColor", SettingText, sizeof(SettingText)))
168 {
169 UiTitleBoxBgColor = UiTextToColor(SettingText);
170 }
171 if (IniReadSettingByName(SectionId, "MessageBoxTextColor", SettingText, sizeof(SettingText)))
172 {
173 UiMessageBoxFgColor = UiTextToColor(SettingText);
174 }
175 if (IniReadSettingByName(SectionId, "MessageBoxColor", SettingText, sizeof(SettingText)))
176 {
177 UiMessageBoxBgColor = UiTextToColor(SettingText);
178 }
179 if (IniReadSettingByName(SectionId, "MenuTextColor", SettingText, sizeof(SettingText)))
180 {
181 UiMenuFgColor = UiTextToColor(SettingText);
182 }
183 if (IniReadSettingByName(SectionId, "MenuColor", SettingText, sizeof(SettingText)))
184 {
185 UiMenuBgColor = UiTextToColor(SettingText);
186 }
187 if (IniReadSettingByName(SectionId, "TextColor", SettingText, sizeof(SettingText)))
188 {
189 UiTextColor = UiTextToColor(SettingText);
190 }
191 if (IniReadSettingByName(SectionId, "SelectedTextColor", SettingText, sizeof(SettingText)))
192 {
193 UiSelectedTextColor = UiTextToColor(SettingText);
194 }
195 if (IniReadSettingByName(SectionId, "SelectedColor", SettingText, sizeof(SettingText)))
196 {
197 UiSelectedTextBgColor = UiTextToColor(SettingText);
198 }
199 if (IniReadSettingByName(SectionId, "EditBoxTextColor", SettingText, sizeof(SettingText)))
200 {
201 UiEditBoxTextColor = UiTextToColor(SettingText);
202 }
203 if (IniReadSettingByName(SectionId, "EditBoxColor", SettingText, sizeof(SettingText)))
204 {
205 UiEditBoxBgColor = UiTextToColor(SettingText);
206 }
207 if (IniReadSettingByName(SectionId, "SpecialEffects", SettingText, sizeof(SettingText)))
208 {
209 UiUseSpecialEffects = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
210 }
211 if (IniReadSettingByName(SectionId, "ShowTime", SettingText, sizeof(SettingText)))
212 {
213 UiDrawTime = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
214 }
215 if (IniReadSettingByName(SectionId, "MenuBox", SettingText, sizeof(SettingText)))
216 {
217 UiMenuBox = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
218 }
219 if (IniReadSettingByName(SectionId, "CenterMenu", SettingText, sizeof(SettingText)))
220 {
221 UiCenterMenu = (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3);
222 }
223 }
224
225 // Draw the backdrop and fade it in if special effects are enabled
226 UiFadeInBackdrop();
227
228 TRACE("UiInitialize() returning TRUE.\n");
229 return TRUE;
230 }
231
232 VOID UiUnInitialize(PCSTR BootText)
233 {
234 UiDrawBackdrop();
235 UiDrawStatusText(BootText);
236 UiInfoBox(BootText);
237
238 UiVtbl.UnInitialize();
239 }
240
241 VOID UiDrawBackdrop(VOID)
242 {
243 UiVtbl.DrawBackdrop();
244 }
245
246 VOID UiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, CHAR FillChar, UCHAR Attr /* Color Attributes */)
247 {
248 UiVtbl.FillArea(Left, Top, Right, Bottom, FillChar, Attr);
249 }
250
251 VOID UiDrawShadow(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom)
252 {
253 UiVtbl.DrawShadow(Left, Top, Right, Bottom);
254 }
255
256 VOID UiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyle, UCHAR HorzStyle, BOOLEAN Fill, BOOLEAN Shadow, UCHAR Attr)
257 {
258 UiVtbl.DrawBox(Left, Top, Right, Bottom, VertStyle, HorzStyle, Fill, Shadow, Attr);
259 }
260
261 VOID UiDrawText(ULONG X, ULONG Y, PCSTR Text, UCHAR Attr)
262 {
263 UiVtbl.DrawText(X, Y, Text, Attr);
264 }
265
266 VOID UiDrawText2(ULONG X, ULONG Y, ULONG MaxNumChars, PCSTR Text, UCHAR Attr)
267 {
268 UiVtbl.DrawText2(X, Y, MaxNumChars, Text, Attr);
269 }
270
271 VOID UiDrawCenteredText(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, PCSTR TextString, UCHAR Attr)
272 {
273 UiVtbl.DrawCenteredText(Left, Top, Right, Bottom, TextString, Attr);
274 }
275
276 VOID UiDrawStatusText(PCSTR StatusText)
277 {
278 UiVtbl.DrawStatusText(StatusText);
279 }
280
281 VOID UiUpdateDateTime(VOID)
282 {
283 UiVtbl.UpdateDateTime();
284 }
285
286 VOID UiInfoBox(PCSTR MessageText)
287 {
288 SIZE_T TextLength;
289 ULONG BoxWidth;
290 ULONG BoxHeight;
291 ULONG LineBreakCount;
292 SIZE_T Index;
293 SIZE_T LastIndex;
294 ULONG Left;
295 ULONG Top;
296 ULONG Right;
297 ULONG Bottom;
298
299 TextLength = strlen(MessageText);
300
301 // Count the new lines and the box width
302 LineBreakCount = 0;
303 BoxWidth = 0;
304 LastIndex = 0;
305 for (Index=0; Index<TextLength; Index++)
306 {
307 if (MessageText[Index] == '\n')
308 {
309 LastIndex = Index;
310 LineBreakCount++;
311 }
312 else
313 {
314 if ((Index - LastIndex) > BoxWidth)
315 {
316 BoxWidth = (ULONG)(Index - LastIndex);
317 }
318 }
319 }
320
321 // Calc the box width & height
322 BoxWidth += 6;
323 BoxHeight = LineBreakCount + 4;
324
325 // Calc the box coordinates
326 Left = (UiScreenWidth / 2) - (BoxWidth / 2);
327 Top =(UiScreenHeight / 2) - (BoxHeight / 2);
328 Right = (UiScreenWidth / 2) + (BoxWidth / 2);
329 Bottom = (UiScreenHeight / 2) + (BoxHeight / 2);
330
331 // Draw the box
332 UiDrawBox(Left,
333 Top,
334 Right,
335 Bottom,
336 VERT,
337 HORZ,
338 TRUE,
339 TRUE,
340 ATTR(UiMenuFgColor, UiMenuBgColor)
341 );
342
343 // Draw the text
344 UiDrawCenteredText(Left, Top, Right, Bottom, MessageText, ATTR(UiTextColor, UiMenuBgColor));
345 }
346
347 VOID UiMessageBox(PCSTR Format, ...)
348 {
349 CHAR Buffer[256];
350 va_list ap;
351
352 va_start(ap, Format);
353 vsnprintf(Buffer, sizeof(Buffer) - sizeof(CHAR), Format, ap);
354 UiVtbl.MessageBox(Buffer);
355 va_end(ap);
356 }
357
358 VOID UiMessageBoxCritical(PCSTR MessageText)
359 {
360 UiVtbl.MessageBoxCritical(MessageText);
361 }
362
363 UCHAR UiTextToColor(PCSTR ColorText)
364 {
365 return UiVtbl.TextToColor(ColorText);
366 }
367
368 UCHAR UiTextToFillStyle(PCSTR FillStyleText)
369 {
370 return UiVtbl.TextToFillStyle(FillStyleText);
371 }
372
373 VOID UiDrawProgressBarCenter(ULONG Position, ULONG Range, PCHAR ProgressText)
374 {
375 UiVtbl.DrawProgressBarCenter(Position, Range, ProgressText);
376 }
377
378 VOID UiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG Position, ULONG Range, PCHAR ProgressText)
379 {
380 UiVtbl.DrawProgressBar(Left, Top, Right, Bottom, Position, Range, ProgressText);
381 }
382
383 VOID UiShowMessageBoxesInSection(PCSTR SectionName)
384 {
385 ULONG Idx;
386 CHAR SettingName[80];
387 CHAR SettingValue[80];
388 PCHAR MessageBoxText;
389 ULONG MessageBoxTextSize;
390 ULONG_PTR SectionId;
391
392 if (!IniOpenSection(SectionName, &SectionId))
393 {
394 return;
395 }
396
397 //
398 // Find all the message box settings and run them
399 //
400 for (Idx=0; Idx<IniGetNumSectionItems(SectionId); Idx++)
401 {
402 IniReadSettingByNumber(SectionId, Idx, SettingName, sizeof(SettingName), SettingValue, sizeof(SettingValue));
403
404 if (_stricmp(SettingName, "MessageBox") == 0)
405 {
406 // Get the real length of the MessageBox text
407 MessageBoxTextSize = IniGetSectionSettingValueSize(SectionId, Idx);
408
409 //if (MessageBoxTextSize > 0)
410 {
411 // Allocate enough memory to hold the text
412 MessageBoxText = FrLdrTempAlloc(MessageBoxTextSize, TAG_UI_TEXT);
413
414 if (MessageBoxText)
415 {
416 // Get the MessageBox text
417 IniReadSettingByNumber(SectionId, Idx, SettingName, sizeof(SettingName), MessageBoxText, MessageBoxTextSize);
418
419 // Fix it up
420 UiEscapeString(MessageBoxText);
421
422 // Display it
423 UiMessageBox(MessageBoxText);
424
425 // Free the memory
426 FrLdrTempFree(MessageBoxText, TAG_UI_TEXT);
427 }
428 }
429 }
430 }
431 }
432
433 VOID UiEscapeString(PCHAR String)
434 {
435 ULONG Idx;
436
437 for (Idx=0; Idx<strlen(String); Idx++)
438 {
439 // Escape the new line characters
440 if (String[Idx] == '\\' && String[Idx+1] == 'n')
441 {
442 // Escape the character
443 String[Idx] = '\n';
444
445 // Move the rest of the string up
446 strcpy(&String[Idx+1], &String[Idx+2]);
447 }
448 }
449 }
450
451 VOID UiTruncateStringEllipsis(PCHAR StringText, ULONG MaxChars)
452 {
453 if (strlen(StringText) > MaxChars)
454 {
455 strcpy(&StringText[MaxChars - 3], "...");
456 }
457 }
458
459 BOOLEAN UiDisplayMenu(PCSTR MenuHeader, PCSTR MenuFooter, BOOLEAN ShowBootOptions, PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOLEAN CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter)
460 {
461 return UiVtbl.DisplayMenu(MenuHeader, MenuFooter, ShowBootOptions, MenuItemList, MenuItemCount, DefaultMenuItem, MenuTimeOut, SelectedMenuItem, CanEscape, KeyPressFilter);
462 }
463
464 VOID UiFadeInBackdrop(VOID)
465 {
466 UiVtbl.FadeInBackdrop();
467 }
468
469 VOID UiFadeOut(VOID)
470 {
471 UiVtbl.FadeOut();
472 }
473
474 BOOLEAN UiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
475 {
476 return UiVtbl.EditBox(MessageText, EditTextBuffer, Length);
477 }
478
479 #else
480 BOOLEAN UiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
481 {
482 return FALSE;
483 }
484 #endif